Skip to content

Commit

Permalink
[Network] BREAKING CHANGE: az network watcher flow-log: Add support…
Browse files Browse the repository at this point in the history
… for `--vnet`, `--subnet`, `--nic` as targetId (#23231)

* VnetFlowLogging changes for AzCLI

* Config command changes and help statements

* Update testcases and config command

* pylint fix

Co-authored-by: Sakthi-Maheswari <[email protected]>
  • Loading branch information
srisakthimaheswari and Sakthi-Maheswari authored Jul 27, 2022
1 parent eb6948e commit 3cee388
Show file tree
Hide file tree
Showing 9 changed files with 12,808 additions and 11 deletions.
68 changes: 68 additions & 0 deletions src/azure-cli/azure/cli/command_modules/network/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -7077,13 +7077,59 @@
--name MyFlowLog
--nsg MyNetworkSecurityGroupName
--storage-account account
- name: Create a flow log with VNet name
text: >
az network watcher flow-log create
--location westus
--resource-group MyResourceGroup
--name MyFlowLog
--vnet MyVNetName
--storage-account account
- name: Create a flow log with Subnet name
text: >
az network watcher flow-log create
--location westus
--resource-group MyResourceGroup
--name MyFlowLog
--vnet MyVNetName
--subnet MySubnetName
--storage-account account
- name: Create a flow log with NIC name
text: >
az network watcher flow-log create
--location westus
--resource-group MyResourceGroup
--name MyFlowLog
--nic MyNICName
--storage-account account
- name: Create a flow log with Network Security Group ID (could be in other resource group)
text: >
az network watcher flow-log create
--location westus
--name MyFlowLog
--nsg MyNetworkSecurityGroupID
--storage-account account
- name: Create a flow log with Virtual Network ID (could be in other resource group)
text: >
az network watcher flow-log create
--location westus
--name MyFlowLog
--vnet MyVNetID
--storage-account account
- name: Create a flow log with Subnet ID (could be in other resource group)
text: >
az network watcher flow-log create
--location westus
--name MyFlowLog
--subnet SubnetID
--storage-account account
- name: Create a flow log with Network Interface ID (could be in other resource group)
text: >
az network watcher flow-log create
--location westus
--name MyFlowLog
--nic MyNetworkInterfaceID
--storage-account account
"""

helps['network watcher flow-log list'] = """
Expand Down Expand Up @@ -7141,6 +7187,28 @@
--resource-group MyAnotherResourceGroup
--name MyFlowLog
--nsg MyNSG
- name: Update Virtual Network on another resource group
text: >
az network watcher flow-log update
--location westus
--resource-group MyAnotherResourceGroup
--name MyFlowLog
--vnet MyVNet
- name: Update Subnet on another resource group
text: >
az network watcher flow-log update
--location westus
--resource-group MyAnotherResourceGroup
--name MyFlowLog
--vnet MyVNet
--subnet MySubnet
- name: Update Network Interface on another resource group
text: >
az network watcher flow-log update
--location westus
--resource-group MyAnotherResourceGroup
--name MyFlowLog
--nic MyNIC
- name: Update Workspace on another resource group
text: >
az network watcher flow-log update
Expand Down
3 changes: 3 additions & 0 deletions src/azure-cli/azure/cli/command_modules/network/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -1723,6 +1723,9 @@ 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('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.')

# temporary solution for compatible with old show command's parameter
# after old show command's parameter is deprecated and removed,
Expand Down
55 changes: 55 additions & 0 deletions src/azure-cli/azure/cli/command_modules/network/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,30 @@ def process_nw_test_connectivity_namespace(cmd, namespace):
namespace.headers = headers


def _process_vnet_name_and_id(vnet, cmd, resource_group_name):
from msrestazure.tools import is_valid_resource_id, resource_id
if vnet and not is_valid_resource_id(vnet):
vnet = resource_id(
subscription=get_subscription_id(cmd.cli_ctx),
resource_group=resource_group_name,
namespace='Microsoft.Network',
type='virtualNetworks',
name=vnet)
return vnet


def _process_subnet_name_and_id(subnet, vnet, cmd, resource_group_name):
from azure.cli.core.azclierror import UnrecognizedArgumentError
from msrestazure.tools import is_valid_resource_id
if subnet and not is_valid_resource_id(subnet):
vnet = _process_vnet_name_and_id(vnet, cmd, resource_group_name)
if vnet is None:
raise UnrecognizedArgumentError('vnet should be provided when input subnet name instead of subnet id')

subnet = vnet + f'/subnets/{subnet}'
return subnet


def process_nw_flow_log_create_namespace(cmd, namespace):
"""
Flow Log is the sub-resource of Network Watcher, they must be in the same region and subscription.
Expand All @@ -1541,10 +1565,41 @@ 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))

# for both create and update
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
}
namespace.vnet = resource_id(**kwargs)
if namespace.subnet and not is_valid_resource_id(namespace.subnet):
namespace.subnet = _process_subnet_name_and_id(
namespace.subnet, namespace.vnet,
cmd, namespace.resource_group_name)
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
}
namespace.nic = resource_id(**kwargs)
if namespace.nsg and not is_valid_resource_id(namespace.nsg):
kwargs = {
'subscription': get_subscription_id(cmd.cli_ctx),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1200,7 +1200,7 @@ def _make_singular(value):
'set_nsg_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)
g.custom_show_command('show', 'show_nw_flow_logging', validator=process_nw_flow_log_show_namespace)

with self.command_group('network watcher flow-log',
network_watcher_flow_log_sdk,
Expand Down
46 changes: 36 additions & 10 deletions src/azure-cli/azure/cli/command_modules/network/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

from azure.cli.core.util import CLIError, sdk_no_wait, find_child_item, find_child_collection
from azure.cli.core.azclierror import InvalidArgumentValueError, RequiredArgumentMissingError, \
UnrecognizedArgumentError, ResourceNotFoundError, CLIInternalError, ArgumentUsageError
UnrecognizedArgumentError, ResourceNotFoundError, CLIInternalError, ArgumentUsageError, \
MutuallyExclusiveArgumentError
from azure.cli.core.profiles import ResourceType, supported_api_version

from azure.cli.command_modules.network._client_factory import network_client_factory
Expand Down Expand Up @@ -6309,7 +6310,6 @@ def set_nsg_flow_logging(cmd, client, watcher_rg, watcher_name, nsg, storage_acc
config = LongRunningOperation(cmd.cli_ctx)(client.begin_get_flow_log_status(watcher_rg,
watcher_name,
flowlog_status_parameters))

try:
if not config.flow_analytics_configuration.network_watcher_flow_analytics_configuration.workspace_id:
config.flow_analytics_configuration = None
Expand Down Expand Up @@ -6372,8 +6372,8 @@ def set_nsg_flow_logging(cmd, client, watcher_rg, watcher_name, nsg, storage_acc

# combination of resource_group_name and nsg is for old output
# combination of location and flow_log_name is for new output
def show_nsg_flow_logging(cmd, client, watcher_rg, watcher_name, location=None, resource_group_name=None, nsg=None,
flow_log_name=None):
def show_nw_flow_logging(cmd, client, watcher_rg, watcher_name, location=None, resource_group_name=None, nsg=None,
flow_log_name=None):
# deprecated approach to show flow log
if nsg is not None:
flowlog_status_parameters = cmd.get_models('FlowLogStatusParameters')(target_resource_id=nsg)
Expand All @@ -6391,7 +6391,10 @@ def create_nw_flow_log(cmd,
watcher_rg,
watcher_name,
flow_log_name,
nsg,
nsg=None,
vnet=None,
subnet=None,
nic=None,
storage_account=None,
resource_group_name=None,
enabled=None,
Expand All @@ -6403,11 +6406,20 @@ def create_nw_flow_log(cmd,
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)

if sum(map(bool, [vnet, subnet, nic, nsg])) == 0:
raise RequiredArgumentMissingError("Please enter atleast one target resource ID.")
if sum(map(bool, [vnet, nic, nsg])) > 1:
raise MutuallyExclusiveArgumentError("Please enter only one target resource ID.")

if subnet is not None:
flow_log = FlowLog(location=location, target_resource_id=subnet, storage_id=storage_account, enabled=enabled, tags=tags)
elif vnet is not None and subnet is None:
flow_log = FlowLog(location=location, target_resource_id=vnet, storage_id=storage_account, enabled=enabled, tags=tags)
elif nic is not None:
flow_log = FlowLog(location=location, target_resource_id=nic, storage_id=storage_account, enabled=enabled, tags=tags)
elif nsg is not None:
flow_log = FlowLog(location=location, target_resource_id=nsg, storage_id=storage_account, enabled=enabled, tags=tags)

if retention > 0:
RetentionPolicyParameters = cmd.get_models('RetentionPolicyParameters')
Expand Down Expand Up @@ -6458,6 +6470,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,
Expand All @@ -6470,6 +6485,17 @@ def update_nw_flow_log(cmd,
c.set_param('enabled', enabled)
c.set_param('tags', tags)
c.set_param('storage_id', storage_account)

if sum(map(bool, [vnet, nic, nsg])) > 1:
raise MutuallyExclusiveArgumentError("Please enter only one target resource ID.")

if subnet is not None:
c.set_param('target_resource_id', subnet)
elif vnet is not None and subnet is None:
c.set_param('target_resource_id', vnet)
elif nic is not 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:
Expand Down
Loading

0 comments on commit 3cee388

Please sign in to comment.