Skip to content
Open
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
27 changes: 27 additions & 0 deletions src/azure-cli/azure/cli/command_modules/mysql/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,33 @@
text: az mysql flexible-server delete --resource-group testGroup --name testserver --yes
"""

helps['mysql flexible-server rename'] = """
type: command
short-summary: Submit a request to rename an existing MySQL flexible server.
long-summary: >
This preview operation requires rename support to be enabled by the service. It renames the existing server
within the same subscription, resource group, and location; it does not create a replacement server.
The server's resource ID and fully qualified domain name change. Update connection strings and references
to the old resource ID, including infrastructure-as-code state such as Terraform state, after completion.
Do not assume the old endpoint remains available or that the operation has no downtime.
For a primary or replica, verify replication and dependent resource references after the rename.
Availability and restrictions for replication topologies, high availability, and networking are service-controlled.
Return immediately after submission without polling for completion. Output contains statusCode (the initial
HTTP status), content (the initial response body as text), and azureAsyncOperation (the Azure-AsyncOperation
response header, or null if absent). The same output is returned with --no-wait.
Acceptance does not mean the rename has completed. Poll the returned URL using az rest --method get --url URL
until status is Succeeded, Failed, or Canceled. After Succeeded, verify the destination server and replicas.
If the service omits the operation URL, inspect the destination server before considering the rename complete.
If the command is interrupted, check the operation and destination server before retrying.
examples:
- name: Submit a rename and return the initial HTTP response and operation URL.
text: az mysql flexible-server rename --resource-group testGroup --name oldserver --new-name newserver
- name: Submit a rename without prompting for confirmation, using the optional compatibility flag.
text: az mysql flexible-server rename --resource-group testGroup --name oldserver --new-name newserver --no-wait --yes
- name: Rename a server identified by its resource ID.
text: az mysql flexible-server rename --ids /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testGroup/providers/Microsoft.DBforMySQL/flexibleServers/oldserver --new-name newserver
"""

helps['mysql flexible-server restore'] = """
type: command
short-summary: Restore a flexible server from backup.
Expand Down
8 changes: 7 additions & 1 deletion src/azure-cli/azure/cli/command_modules/mysql/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from azure.cli.command_modules.mysql.action import AddArgs
from azure.cli.command_modules.mysql.random.generate import generate_username
from azure.cli.command_modules.mysql._validators import public_access_validator, maintenance_window_validator, ip_address_validator, \
firewall_rule_name_validator, validate_identity, validate_byok_identity, validate_identities, validate_action_name, validate_branch
firewall_rule_name_validator, validate_identity, validate_byok_identity, validate_identities, validate_action_name, validate_branch, validate_server_rename
from azure.cli.core.local_context import LocalContextAttribute, LocalContextAction
from ._util import get_current_time, normalize_mysql_tier
from argcomplete.completers import FilesCompleter
Expand Down Expand Up @@ -426,6 +426,12 @@ def load_arguments(self, _): # pylint: disable=too-many-statements, too-many-
with self.argument_context('mysql flexible-server delete') as c:
c.argument('yes', arg_type=yes_arg_type)

with self.argument_context('mysql flexible-server rename') as c:
c.argument('new_name', options_list=['--new-name'], required=True, validator=validate_server_rename,
help='New name for the existing server. The subscription, resource group, and location do not change.')
c.extra('no_wait', action='store_true',
help='Accepted for compatibility. Rename always returns the initial response without waiting for completion.')

with self.argument_context('mysql flexible-server restore') as c:
c.argument('restore_point_in_time', arg_type=restore_point_in_time_arg_type)
c.argument('source_server', arg_type=source_server_arg_type)
Expand Down
12 changes: 12 additions & 0 deletions src/azure-cli/azure/cli/command_modules/mysql/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,18 @@ def firewall_rule_name_validator(ns):
"and no more than 80 characters in length. ")


def validate_server_rename(namespace):
ids = getattr(namespace, '_ids', None)
if ids:
if len(ids) != 1:
raise InvalidArgumentValueError('Specify exactly one MySQL flexible server resource ID to rename.')
parts = parse_resource_id(ids[0])
if (parts.get('namespace', '').lower() != 'microsoft.dbformysql' or
parts.get('type', '').lower() != 'flexibleservers' or
parts.get('child_name_1')):
raise InvalidArgumentValueError('--ids must identify a MySQL flexible server, not another resource type.')


def validate_server_name(db_context, server_name, type_):
client = db_context.cf_availability(db_context.cmd.cli_ctx, '_')

Expand Down
4 changes: 4 additions & 0 deletions src/azure-cli/azure/cli/command_modules/mysql/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ def load_command_table(self, _):
g.custom_wait_command('wait', 'flexible_server_mysql_get')
g.custom_command('restart', 'flexible_server_restart')
g.custom_command('detach-vnet', 'flexible_server_detach_vnet')
# Register --no-wait explicitly so the command invoker does not discard the initial response.
g.custom_command('rename', 'flexible_server_rename', is_preview=True,
confirmation='Renaming changes the server resource ID and endpoint. '
'Update connection strings and resource references after completion. Continue?')

with self.command_group('mysql flexible-server import', mysql_flexible_servers_sdk,
custom_command_type=mysql_custom,
Expand Down
29 changes: 29 additions & 0 deletions src/azure-cli/azure/cli/command_modules/mysql/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,35 @@ def flexible_server_stop(client, resource_group_name=None, server_name=None, no_
return sdk_no_wait(no_wait, client.begin_stop, resource_group_name, server_name)


def flexible_server_rename(cmd, client, resource_group_name, server_name, new_name, no_wait=False):
if not new_name:
raise InvalidArgumentValueError('--new-name must not be empty.')
new_name = new_name.lower()
if new_name == server_name.lower():
raise InvalidArgumentValueError('--new-name must differ from the current server name, ignoring case.')

source_server = client.get(resource_group_name, server_name)
db_context = DbContext(
cmd=cmd, cf_availability=cf_mysql_check_resource_availability,
cf_availability_without_location=cf_mysql_check_resource_availability_without_location,
location=source_server.location)
validate_server_name(db_context, new_name, DELEGATION_SERVICE_NAME)

parameters = models.Server(
location=source_server.location,
create_mode='Rename',
source_server_resource_id=source_server.id)
responses = []
client.begin_create(
resource_group_name, new_name, parameters, polling=False, raw_response_hook=responses.append)
response = responses[-1].http_response
return {
'statusCode': response.status_code,
'content': response.text(),
'azureAsyncOperation': response.headers.get('Azure-AsyncOperation')
}


def flexible_server_update_set(client, resource_group_name, server_name, parameters):
return client.begin_update(resource_group_name, server_name, parameters)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ def argument(self, argument_name, *args, **settings):
if args:
settings['arg_type'] = args[0]
self.registrations.append((self.command_name, argument_name, settings))

def extra(self, argument_name, *args, **settings):
self.argument(argument_name, *args, **settings)


class _FakeAdvancedThreatProtectionClient:

def begin_update(self, resource_group_name, server_name, advanced_threat_protection_name, parameters):
Expand Down
Loading
Loading