Skip to content

Commit e5716c1

Browse files
{Mysql} az mysql flexible-server import create: Add firewall rule migration from single to flex (#27640)
* added firewall rule changes * u * u * u * u * u
1 parent 4743e75 commit e5716c1

File tree

6 files changed

+133
-144
lines changed

6 files changed

+133
-144
lines changed

src/azure-cli/azure/cli/command_modules/mysql/_client_factory.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,7 @@ def private_dns_link_client_factory(cli_ctx, subscription_id=None):
132132
# Operations for single server
133133
def cf_mysql_servers(cli_ctx, _):
134134
return get_mysql_management_client(cli_ctx).servers
135+
136+
137+
def cf_mysql_firewall_rules(cli_ctx, _):
138+
return get_mysql_management_client(cli_ctx).firewall_rules

src/azure-cli/azure/cli/command_modules/mysql/_params.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ def load_arguments(self, _): # pylint: disable=too-many-statements, too-many-
467467
argument_context_string = 'mysql flexible-server firewall-rule {}'.format(scope)
468468
with self.argument_context(argument_context_string) as c:
469469
c.argument('firewall_rule_name', id_part='child_name_1', options_list=['--rule-name', '-r'], validator=firewall_rule_name_validator,
470-
help='The name of the firewall rule. If name is omitted, default name will be chosen for firewall name. The firewall rule name can only contain 0-9, a-z, A-Z, \'-\' and \'_\'. Additionally, the name of the firewall rule must be at least 3 characters and no more than 128 characters in length. ')
470+
help='The name of the firewall rule. If name is omitted, default name will be chosen for firewall name. The firewall rule name can only contain 0-9, a-z, A-Z, \'-\' and \'_\'. Additionally, the name of the firewall rule must be at least 1 character and no more than 80 characters in length. ')
471471
c.argument('end_ip_address', options_list=['--end-ip-address'], validator=ip_address_validator,
472472
help='The end IP address of the firewall rule. Must be IPv4 format. Use value \'0.0.0.0\' to represent all Azure-internal IP addresses. ')
473473
c.argument('start_ip_address', options_list=['--start-ip-address'], validator=ip_address_validator,

src/azure-cli/azure/cli/command_modules/mysql/_util.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,3 +566,7 @@ def get_single_to_flex_sku_mapping(source_single_server_sku, tier, sku_name):
566566
else:
567567
sku_name = single_to_flex_sku_mapping.get(tier).get(source_single_server_sku.capacity)
568568
return tier, sku_name
569+
570+
571+
def get_firewall_rules_from_paged_response(firewall_rules):
572+
return list(firewall_rules) if isinstance(firewall_rules, ItemPaged) else firewall_rules

src/azure-cli/azure/cli/command_modules/mysql/_validators.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -405,10 +405,10 @@ def _valid_range(addr_range):
405405

406406

407407
def firewall_rule_name_validator(ns):
408-
if not re.search(r'^[a-zA-Z0-9][-_a-zA-Z0-9]{1,126}[_a-zA-Z0-9]$', ns.firewall_rule_name):
408+
if not re.search(r'^[a-zA-Z0-9][-_a-zA-Z0-9]{0,79}(?<!-)$', ns.firewall_rule_name):
409409
raise ValidationError("The firewall rule name can only contain 0-9, a-z, A-Z, \'-\' and \'_\'. "
410-
"Additionally, the name of the firewall rule must be at least 3 characters "
411-
"and no more than 128 characters in length. ")
410+
"Additionally, the name of the firewall rule must be at least 1 character "
411+
"and no more than 80 characters in length. ")
412412

413413

414414
def validate_server_name(db_context, server_name, type_):

src/azure-cli/azure/cli/command_modules/mysql/custom.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@
2323
from azure.cli.core.azclierror import ClientRequestError, RequiredArgumentMissingError, ArgumentUsageError, InvalidArgumentValueError, ValidationError
2424
from ._client_factory import get_mysql_flexible_management_client, cf_mysql_flexible_firewall_rules, cf_mysql_flexible_db, \
2525
cf_mysql_check_resource_availability, cf_mysql_check_resource_availability_without_location, cf_mysql_flexible_config, \
26-
cf_mysql_flexible_servers, cf_mysql_flexible_replica, cf_mysql_flexible_adadmin, cf_mysql_flexible_private_dns_zone_suffix_operations, cf_mysql_servers
26+
cf_mysql_flexible_servers, cf_mysql_flexible_replica, cf_mysql_flexible_adadmin, cf_mysql_flexible_private_dns_zone_suffix_operations, cf_mysql_servers, \
27+
cf_mysql_firewall_rules
2728
from ._util import resolve_poller, generate_missing_parameters, get_mysql_list_skus_info, generate_password, parse_maintenance_window, \
2829
replace_memory_optimized_tier, build_identity_and_data_encryption, get_identity_and_data_encryption, get_tenant_id, run_subprocess, \
29-
run_subprocess_get_output, fill_action_template, get_git_root_dir, get_single_to_flex_sku_mapping, GITHUB_ACTION_PATH
30+
run_subprocess_get_output, fill_action_template, get_git_root_dir, get_single_to_flex_sku_mapping, get_firewall_rules_from_paged_response, GITHUB_ACTION_PATH
3031
from ._network import prepare_mysql_exist_private_dns_zone, prepare_mysql_exist_private_network, prepare_private_network, prepare_private_dns_zone, prepare_public_network
3132
from ._validators import mysql_arguments_validator, mysql_auto_grow_validator, mysql_georedundant_backup_validator, mysql_restore_tier_validator, \
3233
mysql_retention_validator, mysql_sku_name_validator, mysql_storage_validator, validate_mysql_replica, validate_server_name, \
@@ -167,15 +168,16 @@ def database_delete_func(client, resource_group_name=None, server_name=None, dat
167168
return result
168169

169170

170-
def create_firewall_rule(db_context, cmd, resource_group_name, server_name, start_ip, end_ip):
171+
def create_firewall_rule(db_context, cmd, resource_group_name, server_name, start_ip, end_ip, firewall_rule_name=None):
171172
# allow access to azure ip addresses
172173
cf_firewall = db_context.cf_firewall # NOQA pylint: disable=unused-variable
173174
firewall_client = cf_firewall(cmd.cli_ctx, None)
174175
firewall = firewall_rule_create_func(cmd=cmd,
175176
client=firewall_client,
176177
resource_group_name=resource_group_name,
177178
server_name=server_name,
178-
start_ip_address=start_ip, end_ip_address=end_ip)
179+
start_ip_address=start_ip, end_ip_address=end_ip,
180+
firewall_rule_name=firewall_rule_name)
179181
return firewall.result().name
180182

181183

@@ -630,6 +632,13 @@ def flexible_server_import_create(cmd, client,
630632
if start_ip != -1 and end_ip != -1:
631633
firewall_name = create_firewall_rule(db_context, cmd, resource_group_name, server_name, start_ip, end_ip)
632634

635+
# Migrating firewall rules from single server to flexible server
636+
if data_source_type.lower() == 'mysql_single' and create_mode.lower() == 'migrate':
637+
if network.public_network_access.lower() == 'disabled':
638+
logger.warning('Firewall rules cannot be migrated for private access enabled server.')
639+
else:
640+
migrate_firewall_rules_from_single_to_flex(db_context=db_context, cmd=cmd, source_server_id=source_server_id, target_server_name=server_name)
641+
633642
user = server_result.administrator_login
634643
server_id = server_result.id
635644
loc = server_result.location
@@ -1878,6 +1887,25 @@ def flexible_server_export_create(cmd, client, resource_group_name, server_name,
18781887
return resolve_poller(client.begin_create(resource_group_name, server_name, parameters), cmd.cli_ctx, 'Create backup')
18791888

18801889

1890+
def migrate_firewall_rules_from_single_to_flex(db_context, cmd, source_server_id, target_server_name):
1891+
id_parts = parse_resource_id(source_server_id)
1892+
firewall_client = cf_mysql_firewall_rules(cmd.cli_ctx, _=None)
1893+
firewall_rules = get_firewall_rules_from_paged_response(firewall_client.list_by_server(id_parts['resource_group'], id_parts['name']))
1894+
for rule in firewall_rules:
1895+
if not re.search(r'^[a-zA-Z0-9][-_a-zA-Z0-9]{0,79}(?<!-)$', rule.name):
1896+
logger.warning("Could not migrate firewall rule \'%s\' since firewall rule name can only contain 0-9, a-z, A-Z, \'-\' and \'_\'. "
1897+
"Additionally, the name of the firewall rule must be at least 1 character "
1898+
"and no more than 80 characters in length. ", rule.name)
1899+
continue
1900+
create_firewall_rule(db_context=db_context,
1901+
cmd=cmd,
1902+
resource_group_name=id_parts['resource_group'],
1903+
server_name=target_server_name,
1904+
start_ip=rule.start_ip_address,
1905+
end_ip=rule.end_ip_address,
1906+
firewall_rule_name=rule.name)
1907+
1908+
18811909
# pylint: disable=too-many-instance-attributes, too-few-public-methods, useless-object-inheritance
18821910
class DbContext(object):
18831911
def __init__(self, cmd=None, azure_sdk=None, logging_name=None, cf_firewall=None, cf_db=None,

0 commit comments

Comments
 (0)