Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
12 changes: 12 additions & 0 deletions src/azure-cli/azure/cli/command_modules/appservice/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@
text: az functionapp config access-restriction add -g ResourceGroup -n AppName --rule-name remote_agents --action Allow --vnet-name corp01 --subnet agents --priority 500 --vnet-resource-group vnets
- name: Add Access Restriction opening (Allow) named agents in vNet 'corp01' in rg 'vnets' with subnet 'agents' (using subnet resource id)
text: az functionapp config access-restriction add -g ResourceGroup -n AppName --rule-name remote_agents --action Allow --priority 800 --subnet '/subscriptions/<subscription-id>/resourceGroups/vnets/providers/Microsoft.Network/virtualNetworks/corp01/subnets/agents'
- name: Add Access Restriction opening (Allow) with no rule name for service tag AzureCloud
text: az functionapp config access-restriction add -g ResourceGroup -n AppName --priority 400 --service-tag AzureCloud
- name: Add Access Restriction opening (Allow) with no rule name for service tag AzureFrontDoor.Backend and http-header X-Azure-FDID with value '12345678-abcd-1234-abcd-12345678910a'
text: az functionapp config access-restriction add -g ResourceGroup -n AppName --priority 400 --service-tag AzureFrontDoor.Backend --http-header x-azure-fdid=12345678-abcd-1234-abcd-12345678910a
"""

helps['functionapp config access-restriction remove'] = """
Expand All @@ -154,6 +158,8 @@
text: az functionapp config access-restriction remove -g ResourceGroup -n AppName --rule-name developers
- name: Remove Access Restriction named internal_agents from the scm site.
text: az functionapp config access-restriction remove -g ResourceGroup -n AppName --rule-name internal_agents --scm-site true
- name: Remove Access Restriction with service tag AzureFrontDoor.Backend from the main site.
text: az functionapp config access-restriction remove -g ResourceGroup -n AppName --service-tag AzureFrontDoor.Backend
"""

helps['functionapp config access-restriction set'] = """
Expand Down Expand Up @@ -1015,6 +1021,10 @@
text: az webapp config access-restriction add -g ResourceGroup -n AppName --rule-name remote_agents --action Allow --vnet-name corp01 --subnet agents --priority 500 --vnet-resource-group vnets
- name: Add Access Restriction opening (Allow) named agents in vNet 'corp01' in rg 'vnets' with subnet 'agents' (using subnet resource id)
text: az webapp config access-restriction add -g ResourceGroup -n AppName --rule-name remote_agents --action Allow --priority 800 --subnet '/subscriptions/<subscription-id>/resourceGroups/vnets/providers/Microsoft.Network/virtualNetworks/corp01/subnets/agents'
- name: Add Access Restriction opening (Allow) with no rule name for service tag AzureCloud
text: az webapp config access-restriction add -g ResourceGroup -n AppName --priority 400 --service-tag AzureCloud
- name: Add Access Restriction opening (Allow) with no rule name for service tag AzureFrontDoor.Backend and http-header X-Azure-FDID with value '12345678-abcd-1234-abcd-12345678910a'
text: az webapp config access-restriction add -g ResourceGroup -n AppName --priority 400 --service-tag AzureFrontDoor.Backend --http-header x-azure-fdid=12345678-abcd-1234-abcd-12345678910a
"""

helps['webapp config access-restriction remove'] = """
Expand All @@ -1025,6 +1035,8 @@
text: az webapp config access-restriction remove -g ResourceGroup -n AppName --rule-name developers
- name: Remove Access Restriction named internal_agents from the scm site.
text: az webapp config access-restriction remove -g ResourceGroup -n AppName --rule-name internal_agents --scm-site true
- name: Remove Access Restriction with service tag AzureFrontDoor.Backend from the main site.
text: az webapp config access-restriction remove -g ResourceGroup -n AppName --service-tag AzureFrontDoor.Backend
"""

helps['webapp config access-restriction set'] = """
Expand Down
14 changes: 11 additions & 3 deletions src/azure-cli/azure/cli/command_modules/appservice/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
from ._completers import get_hostname_completion_list
from ._constants import FUNCTIONS_VERSIONS, FUNCTIONS_STACKS_API_JSON_PATHS, FUNCTIONS_STACKS_API_KEYS
from ._validators import (validate_timeout_value, validate_site_create, validate_asp_create,
validate_add_vnet, validate_front_end_scale_factor, validate_ase_create, validate_ip_address)
validate_add_vnet, validate_front_end_scale_factor, validate_ase_create, validate_ip_address,
validate_service_tag)

AUTH_TYPES = {
'AllowAnonymous': 'na',
Expand Down Expand Up @@ -863,7 +864,10 @@ def load_arguments(self, _):
c.argument('description', help='Description of the access restriction rule')
c.argument('action', arg_type=get_enum_type(ACCESS_RESTRICTION_ACTION_TYPES),
help="Allow or deny access")
c.argument('ip_address', help="IP address or CIDR range", validator=validate_ip_address)
c.argument('ip_address', help="IP address or CIDR range (optional comma separated list of up to 8 ranges)",
validator=validate_ip_address)
c.argument('service_tag', help="Service Tag (optional comma separated list of up to 8 tags)",
validator=validate_service_tag)
c.argument('vnet_name', help="vNet name")
c.argument('subnet', help="Subnet name (requires vNet name) or subnet resource id")
c.argument('ignore_missing_vnet_service_endpoint',
Expand All @@ -874,11 +878,15 @@ def load_arguments(self, _):
c.argument('scm_site', help='True if access restrictions is added for scm site',
arg_type=get_three_state_flag())
c.argument('vnet_resource_group', help='Resource group of virtual network (default is web app resource group)')
c.argument('http_headers', nargs='+', help="space-separated http headers in a format of `<name>=<value>`")
with self.argument_context(scope + ' config access-restriction remove') as c:
c.argument('name', arg_type=(webapp_name_arg_type if scope == 'webapp' else functionapp_name_arg_type))
c.argument('rule_name', options_list=['--rule-name', '-r'],
help='Name of the access restriction to remove')
c.argument('ip_address', help="IP address or CIDR range", validator=validate_ip_address)
c.argument('ip_address', help="IP address or CIDR range (optional comma separated list of up to 8 ranges)",
validator=validate_ip_address)
c.argument('service_tag', help="Service Tag (optional comma separated list of up to 8 tags)",
validator=validate_service_tag)
c.argument('vnet_name', help="vNet name")
c.argument('subnet', help="Subnet name (requires vNet name) or subnet resource id")
c.argument('scm_site', help='True if access restriction should be removed from scm site',
Expand Down
95 changes: 71 additions & 24 deletions src/azure-cli/azure/cli/command_modules/appservice/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

import ipaddress

from azure.cli.core.azclierror import (InvalidArgumentValueError, ArgumentUsageError)
from azure.cli.core.commands.client_factory import get_mgmt_service_client
from azure.cli.core.profiles import ResourceType
from knack.log import get_logger
from knack.util import CLIError
from msrestazure.tools import is_valid_resource_id, parse_resource_id
from azure.cli.core.commands.client_factory import get_mgmt_service_client

from ._appservice_utils import _generic_site_operation
from ._client_factory import web_client_factory
from .utils import _normalize_sku

logger = get_logger(__name__)


def validate_timeout_value(namespace):
"""Validates that zip deployment timeout is set to a reasonable min value"""
Expand Down Expand Up @@ -65,7 +74,6 @@ def validate_asp_create(cmd, namespace):
if isinstance(namespace.location, str):
location = namespace.location
else:
from azure.cli.core.profiles import ResourceType
rg_client = get_mgmt_service_client(cmd.cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES)

group = rg_client.resource_groups.get(resource_group_name)
Expand Down Expand Up @@ -123,7 +131,6 @@ def validate_add_vnet(cmd, namespace):
vnet_loc = v.location
break

from ._appservice_utils import _generic_site_operation
webapp = _generic_site_operation(cmd.cli_ctx, resource_group_name, name, 'get', slot)
# converting geo region to geo location
webapp_loc = webapp.location.lower().replace(" ", "")
Expand Down Expand Up @@ -164,33 +171,73 @@ def validate_onedeploy_params(namespace):

def _validate_ip_address_format(namespace):
if namespace.ip_address is not None:
# IPv6
if ':' in namespace.ip_address:
if namespace.ip_address.count(':') > 1:
if '/' not in namespace.ip_address:
namespace.ip_address = namespace.ip_address + '/128'
return
return
# IPv4
elif '.' in namespace.ip_address:
if namespace.ip_address.count('.') == 3:
if '/' not in namespace.ip_address:
namespace.ip_address = namespace.ip_address + '/32'
return
return

raise CLIError('Invalid IP address')
input_value = namespace.ip_address
if ' ' in input_value:
raise InvalidArgumentValueError("Spaces not allowed: '{}' ".format(input_value))
input_ips = input_value.split(',')
if len(input_ips) > 8:
raise InvalidArgumentValueError('Maximum 8 IP addresses are allowed per rule.')
validated_ips = ''
for ip in input_ips:
# Use ipaddress library to validate ip network format
ip_obj = ipaddress.ip_network(ip)
validated_ips += str(ip_obj) + ','
namespace.ip_address = validated_ips[:-1]


def _validate_ip_address_existence(cmd, namespace):
resource_group_name = namespace.resource_group_name
name = namespace.name
slot = namespace.slot
scm_site = namespace.scm_site
from ._appservice_utils import _generic_site_operation
configs = _generic_site_operation(cmd.cli_ctx, resource_group_name, name, 'get_configuration', slot)
access_rules = configs.scm_ip_security_restrictions if scm_site else configs.ip_security_restrictions
is_exists = [(lambda x: x.ip_address == namespace.ip_address)(x) for x in access_rules]
if True in is_exists:
raise CLIError('IP address ' + namespace.ip_address + ' already exists. '
'Cannot add duplicate IP address values.')
ip_exists = [(lambda x: x.ip_address == namespace.ip_address)(x) for x in access_rules]
if True in ip_exists:
raise ArgumentUsageError('IP address: ' + namespace.ip_address + ' already exists. '
'Cannot add duplicate IP address values.')


def validate_service_tag(cmd, namespace):
if namespace.service_tag is not None:
_validate_service_tag_format(cmd, namespace)
# For prevention of adding the duplicate IPs.
if 'add' in cmd.name:
_validate_service_tag_existence(cmd, namespace)


def _validate_service_tag_format(cmd, namespace):
if namespace.service_tag is not None:
input_value = namespace.service_tag
if ' ' in input_value:
raise InvalidArgumentValueError("Spaces not allowed: '{}' ".format(input_value))
input_tags = input_value.split(',')
if len(input_tags) > 8:
raise InvalidArgumentValueError('Maximum 8 service tags are allowed per rule.')
network_client = get_mgmt_service_client(cmd.cli_ctx, ResourceType.MGMT_NETWORK)
resource_group_name = namespace.resource_group_name
name = namespace.name
webapp = _generic_site_operation(cmd.cli_ctx, resource_group_name, name, 'get')
service_tag_full_list = network_client.service_tags.list(webapp.location).values
for tag in input_tags:
valid_tag = False
for tag_full_list in service_tag_full_list:
if tag.lower() == tag_full_list.name.lower():
valid_tag = True
continue
if not valid_tag:
raise InvalidArgumentValueError('Unknown Service Tag: ' + tag)


def _validate_service_tag_existence(cmd, namespace):
resource_group_name = namespace.resource_group_name
name = namespace.name
slot = namespace.slot
scm_site = namespace.scm_site
input_tag_value = namespace.service_tag.replace(' ', '')
configs = _generic_site_operation(cmd.cli_ctx, resource_group_name, name, 'get_configuration', slot)
access_rules = configs.scm_ip_security_restrictions if scm_site else configs.ip_security_restrictions
for rule in access_rules:
if rule.ip_address and rule.ip_address.lower() == input_tag_value.lower():
raise ArgumentUsageError('Service Tag: ' + namespace.service_tag + ' already exists. '
'Cannot add duplicate Service Tag values.')
Loading