Skip to content

Commit 55e3ba6

Browse files
committed
Add fabric mirroring CLI commands: az mysql flexible-server mirroing enable/disable
1 parent f1c087e commit 55e3ba6

6 files changed

Lines changed: 137 additions & 2 deletions

File tree

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
@@ -141,6 +141,10 @@ def private_dns_link_client_factory(cli_ctx, subscription_id=None):
141141
subscription_id=subscription_id).virtual_network_links
142142

143143

144+
def cf_mysql_flexible_fabric_mirroring_settings(cli_ctx, _):
145+
return get_mysql_flexible_management_client(cli_ctx).fabric_mirroring_settings
146+
147+
144148
# Operations for single server
145149
def cf_mysql_servers(cli_ctx, _):
146150
return get_mysql_management_client(cli_ctx).servers

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,3 +902,33 @@
902902
- name: Create a export backup for 'testsvr' with backup name 'testbackup'.
903903
text: az mysql flexible-server export create -g testgroup -n testsvr -b testbackup -u destsasuri
904904
"""
905+
906+
helps['mysql flexible-server mirroring'] = """
907+
type: group
908+
short-summary: Manage Microsoft Fabric Mirroring for Azure Database for MySQL Flexible Server.
909+
long-summary: |
910+
Fabric Mirroring allows continuous data replication from MySQL Flexible Server into Microsoft Fabric for analytics and reporting.
911+
"""
912+
913+
helps['mysql flexible-server mirroring enable'] = """
914+
type: command
915+
short-summary: Enable Fabric Mirroring for a MySQL Flexible Server.
916+
long-summary: |
917+
Configures the server for Fabric Mirroring.
918+
Requires a User Assigned Managed Identity (UAMI) resource ID with appropriate permissions.
919+
examples:
920+
- name: Enable Fabric Mirroring for server 'testsvr' using a User Assigned Managed Identity.
921+
text: >
922+
az mysql flexible-server mirroring enable -g testgroup -n testsvr \
923+
--identity-resource-id /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<name>
924+
"""
925+
926+
helps['mysql flexible-server mirroring disable'] = """
927+
type: command
928+
short-summary: Disable Fabric Mirroring for a MySQL Flexible Server.
929+
long-summary: |
930+
Removes Fabric Mirroring configuration from the server.
931+
examples:
932+
- name: Disable Fabric Mirroring for server 'testsvr'.
933+
text: az mysql flexible-server mirroring disable -g testgroup -n testsvr
934+
"""

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,3 +736,10 @@ def load_arguments(self, _): # pylint: disable=too-many-statements, too-many-
736736
elif scope == "check-name-availability":
737737
c.argument('migration_name', arg_type=migration_id_arg_type, options_list=['--migration-name'],
738738
help='Name of the migration.')
739+
740+
with self.argument_context('mysql flexible-server mirroring enable') as c:
741+
c.argument('server_name', id_part=None, arg_type=server_name_arg_type)
742+
c.argument('uami', options_list=['--identity-resource-id'], help='Resource ID of the User Assigned Managed Identity (UAMI) used for Fabric Mirroring. Example: /subscriptions/{sub-id}/resourceGroups/{rg}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identity-name}')
743+
744+
with self.argument_context('mysql flexible-server mirroring disable') as c:
745+
c.argument('server_name', id_part=None, arg_type=server_name_arg_type)

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
# Copyright (c) Microsoft Corporation. All rights reserved.
33
# Licensed under the MIT License. See License.txt in the project root for license information.
44
# --------------------------------------------------------------------------------------------
5-
65
from azure.cli.core.commands import CliCommandType
76
from azure.cli.command_modules.mysql._client_factory import (
87
cf_mysql_advanced_threat_protection,
@@ -17,7 +16,8 @@
1716
cf_mysql_flexible_backups,
1817
cf_mysql_flexible_adadmin,
1918
cf_mysql_flexible_export,
20-
cf_mysql_flexible_maintenances)
19+
cf_mysql_flexible_maintenances,
20+
cf_mysql_flexible_fabric_mirroring_settings)
2121
from ._transformers import (
2222
table_transform_output,
2323
table_transform_output_list_servers,
@@ -95,6 +95,11 @@ def load_command_table(self, _):
9595
client_factory=cf_mysql_flexible_maintenances
9696
)
9797

98+
mysql_flexible_fabric_mirroring_settings_sdk = CliCommandType(
99+
operations_tmpl='azure.mgmt.rdbms.mysql_flexibleservers.operations#FabricMirroringSettingsOperations.{}',
100+
client_factory=cf_mysql_flexible_fabric_mirroring_settings
101+
)
102+
98103
# MERU COMMANDS
99104
mysql_custom = CliCommandType(operations_tmpl='azure.cli.command_modules.mysql.custom#{}')
100105

@@ -236,3 +241,10 @@ def load_command_table(self, _):
236241
g.custom_command('reschedule', 'flexible_server_maintenance_reschedule')
237242
g.custom_command('list', 'flexible_server_maintenance_list')
238243
g.custom_show_command('show', 'flexible_server_maintenance_show')
244+
245+
with self.command_group('mysql flexible-server mirroring',
246+
mysql_flexible_fabric_mirroring_settings_sdk,
247+
custom_command_type=mysql_custom,
248+
client_factory=cf_mysql_flexible_fabric_mirroring_settings) as g:
249+
g.custom_command('enable', 'flexible_server_mirroring_enable')
250+
g.custom_command('disable', 'flexible_server_mirroring_disable')

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# -*- coding: utf-8 -*-
12
# --------------------------------------------------------------------------------------------
23
# Copyright (c) Microsoft Corporation. All rights reserved.
34
# Licensed under the MIT License. See License.txt in the project root for license information.
@@ -2023,6 +2024,49 @@ def migrate_firewall_rules_from_single_to_flex(db_context, cmd, source_server_id
20232024
firewall_rule_name=rule.name)
20242025

20252026

2027+
def _fm_settings_payload(state, uami=None):
2028+
"""
2029+
Build the flattened payload expected by the SDK for FabricMirroringSettings.
2030+
Because of x-ms-client-flatten, we set properties at the top level.
2031+
"""
2032+
# Most recent autorest will let us pass state/identityResourceId directly on the Settings model
2033+
return mysql_models.FabricMirroringSettings(
2034+
state=state,
2035+
identity_resource_id=uami # optional when disabling
2036+
)
2037+
2038+
2039+
def flexible_server_mirroring_enable(cmd, client, resource_group_name, server_name, identity_resource_id):
2040+
"""
2041+
'Enable' translates to PUT the 'Default' FabricMirroringSettings with state=Enabled and UAMI.
2042+
The Swagger limits settings name to 'Default'.
2043+
"""
2044+
if not identity_resource_id:
2045+
raise RequiredArgumentMissingError(
2046+
"Parameter --identity-resource-id is required when enabling fabric mirroring."
2047+
)
2048+
2049+
payload = _fm_settings_payload(state='Enabled', uami=identity_resource_id)
2050+
2051+
# Long-running operation
2052+
poller = (getattr(client, 'begin_create_or_update', None) or getattr(client, 'begin_put'))(
2053+
resource_group_name, server_name, 'Default', payload
2054+
)
2055+
return resolve_poller(poller, cmd.cli_ctx, 'Enable Fabric mirroring')
2056+
2057+
2058+
def flexible_server_mirroring_disable(cmd, client, resource_group_name, server_name):
2059+
"""
2060+
'Disable' translates to PUT the 'Default' FabricMirroringSettings with state=Disabled.
2061+
identityResourceId can be omitted when disabling<97>service will deactivate/clean bindings.
2062+
"""
2063+
payload = _fm_settings_payload(state='Disabled', uami=None)
2064+
poller = (getattr(client, 'begin_create_or_update', None) or getattr(client, 'begin_put'))(
2065+
resource_group_name, server_name, 'Default', payload
2066+
)
2067+
return resolve_poller(poller, cmd.cli_ctx, 'Disable Fabric mirroring')
2068+
2069+
20262070
# pylint: disable=too-many-instance-attributes, too-few-public-methods
20272071
class DbContext:
20282072
def __init__(self, cmd=None, azure_sdk=None, logging_name=None, cf_firewall=None, cf_db=None,

src/azure-cli/azure/cli/command_modules/mysql/tests/latest/test_mysql_scenario.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2351,3 +2351,41 @@ def _test_flexible_server_export_create_mgmt(self, database_engine, resource_gro
23512351

23522352
# deletion of single server created
23532353
self.cmd('{} flexible-server delete -g {} -n {} --yes'.format(database_engine, resource_group, server), checks=NoneCheck())
2354+
2355+
2356+
class MySQLFabricMirroringEnableDisableTest(ScenarioTest):
2357+
"""Scenario tests for Fabric Mirroring enable/disable commands."""
2358+
2359+
@AllowLargeResponse()
2360+
@ResourceGroupPreparer(location='eastus2euap')
2361+
def test_mysql_fabric_mirroring_enable_disable(self, resource_group):
2362+
# Arrange
2363+
server_name = self.create_random_name(SERVER_NAME_PREFIX, SERVER_NAME_MAX_LENGTH)
2364+
identity_name = self.create_random_name('identity', 24)
2365+
location = 'eastus2euap'
2366+
2367+
# Create server (GeneralPurpose tier required for Fabric Mirroring, using Standard_D2ads_v5 valid in eastus2euap)
2368+
create_result = self.cmd('mysql flexible-server create -l {} -g {} -n {} --public-access {} --tier GeneralPurpose --sku-name {}'
2369+
.format(location, resource_group, server_name, '0.0.0.0', 'Standard_D2ads_v5')).get_output_in_json()
2370+
2371+
# Verify server was created by checking the host contains the server name
2372+
self.assertIn(server_name, create_result['host'])
2373+
2374+
# Set binlog_row_image to 'noblob' as required for Fabric Mirroring
2375+
self.cmd('mysql flexible-server parameter set -g {} -s {} -n binlog_row_image -v noblob'
2376+
.format(resource_group, server_name))
2377+
2378+
# Create User Assigned Managed Identity
2379+
identity_result = self.cmd('identity create -g {} -n {}'.format(resource_group, identity_name)).get_output_in_json()
2380+
identity_id = identity_result['id']
2381+
2382+
# Enable Fabric Mirroring
2383+
self.cmd('mysql flexible-server mirroring enable -g {} -n {} --identity-resource-id {}'
2384+
.format(resource_group, server_name, identity_id))
2385+
2386+
# Disable Fabric Mirroring
2387+
self.cmd('mysql flexible-server mirroring disable -g {} -n {}'
2388+
.format(resource_group, server_name))
2389+
2390+
# Cleanup
2391+
self.cmd('mysql flexible-server delete -g {} -n {} --yes'.format(resource_group, server_name))

0 commit comments

Comments
 (0)