Skip to content

Conversation

rambabu-yalla
Copy link

@rambabu-yalla rambabu-yalla commented Sep 18, 2025

…ver restore

Description

Mandatory Checklist

  • SHOULD update ChangeLog.md file(s) appropriately
    • Update src/{{SERVICE}}/{{SERVICE}}/ChangeLog.md.
      • A snippet outlining the change(s) made in the PR should be written under the ## Upcoming Release header in the past tense.
    • Should not change ChangeLog.md if no new release is required, such as fixing test case only.
  • SHOULD regenerate markdown help files if there is cmdlet API change. Instruction
  • SHOULD have proper test coverage for changes in pull request.
  • SHOULD NOT adjust version of module manually in pull request

@Copilot Copilot AI review requested due to automatic review settings September 18, 2025 11:59
Copy link

Thanks for your contribution! The pull request validation has started. Please revisit this comment for updated status.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces support for self-service restore functionality for SQL logical servers by adding soft-delete retention capabilities and a new restore cmdlet. The changes allow users to configure retention periods for deleted servers and restore them within that timeframe.

Key changes:

  • Added soft-delete retention parameters to New-AzSqlServer and Set-AzSqlServer cmdlets
  • Introduced new Restore-AzSqlServer cmdlet for restoring deleted servers
  • Updated the underlying data model and service layer to support retention functionality

Reviewed Changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/Sql/Sql/help/Set-AzSqlServer.md Added documentation for new retention parameters
src/Sql/Sql/help/Restore-AzSqlServer.md Added help documentation for new restore cmdlet
src/Sql/Sql/help/New-AzSqlServer.md Added documentation for soft-delete retention parameters
src/Sql/Sql/Server/Services/AzureSqlServerCommunicator.cs Added method to retrieve deleted servers
src/Sql/Sql/Server/Services/AzureSqlServerAdapter.cs Added support for retention days and create mode in server operations
src/Sql/Sql/Server/Model/AzureSqlServerModel.cs Extended model with retention and create mode properties
src/Sql/Sql/Server/Cmdlet/SetAzureSqlServer.cs Added retention parameters and logic
src/Sql/Sql/Server/Cmdlet/RestoreAzureSqlServer.cs New cmdlet implementation for server restoration
src/Sql/Sql/Server/Cmdlet/NewAzureSqlServer.cs Added soft-delete retention parameters
src/Sql/Sql/ChangeLog.md Updated changelog with feature description
src/Sql/Sql/Az.Sql.psd1 Added new Restore-AzSqlServer cmdlet to exports
src/Sql/Sql.Management.Sdk/README.md Updated SDK configuration with new API specifications

Sid = this.ExternalAdminSID
}
},
RetentionDays = (this.EnableSoftDeleteRetention && !this.SoftDeleteRetentionDays.HasValue) ? 7 : this.SoftDeleteRetentionDays

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we still covered for the scenario of SoftDeleteRetentionDays being null and EnableSoftDeleteRetention not being passed (i.e. using default value of false)?

@VeryEarly VeryEarly self-assigned this Sep 19, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • src/Sql/Sql/Properties/Resources.Designer.cs: Language not supported

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • src/Sql/Sql/Properties/Resources.Designer.cs: Language not supported

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • src/Sql/Sql/Properties/Resources.Designer.cs: Language not supported

[Parameter(Mandatory = false,
HelpMessage = "Specify whether to enable soft-delete retention for the server. When enabled, a dropped server can be restored within the retention window (defaults to 7 days if not specified). To set a custom retention period use -SoftDeleteRetentionDays.")]
[PSArgumentCompleter("true", "false")]
public bool EnableSoftDeleteRetention { get; set; } = false;
Copy link
Preview

Copilot AI Sep 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The default value assignment here is redundant since bool properties default to false. Consider removing the explicit assignment for cleaner code.

Suggested change
public bool EnableSoftDeleteRetention { get; set; } = false;
public bool EnableSoftDeleteRetention { get; set; }

Copilot uses AI. Check for mistakes.

/// </summary>
[Parameter(Mandatory = false,
HelpMessage = "Specify whether to enable soft-delete retention for the server. When enabled, a dropped server can be restored within the retention window (defaults to 7 days if not specified). To set a custom retention period use -SoftDeleteRetentionDays.")]
public bool EnableSoftDeleteRetention { get; set; } = false;
Copy link
Preview

Copilot AI Sep 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The default value assignment here is redundant since bool properties default to false. Consider removing the explicit assignment for cleaner code.

Suggested change
public bool EnableSoftDeleteRetention { get; set; } = false;
public bool EnableSoftDeleteRetention { get; set; }

Copilot uses AI. Check for mistakes.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 5 comments.

Files not reviewed (1)
  • src/Sql/Sql/Properties/Resources.Designer.cs: Language not supported

```
### -EnableSoftDeleteRetention
Boolean value for whether or not to enable soft-delete for the server such that the server can be restored for a default of 7 days after dropping. If you want to specify a different retention period, use the RetentionDays parameter.
Copy link
Preview

Copilot AI Sep 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter description references 'RetentionDays parameter' but the actual parameter name is 'SoftDeleteRetentionDays'. This should be corrected to match the actual parameter name for clarity.

Suggested change
Boolean value for whether or not to enable soft-delete for the server such that the server can be restored for a default of 7 days after dropping. If you want to specify a different retention period, use the RetentionDays parameter.
Boolean value for whether or not to enable soft-delete for the server such that the server can be restored for a default of 7 days after dropping. If you want to specify a different retention period, use the SoftDeleteRetentionDays parameter.

Copilot uses AI. Check for mistakes.

```
### -SoftDeleteRetentionDays
Value for soft-delete retention days for the server such that the server can be restored for the specified number of days after dropping. Only valid values are from 0 to 35. If set to 0, soft-delete retention is disabled.
Copy link
Preview

Copilot AI Sep 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description states valid values are '0 to 35' but should be '0-35' to match the format used in other parameter descriptions and the ValidateRange attribute in the code.

Suggested change
Value for soft-delete retention days for the server such that the server can be restored for the specified number of days after dropping. Only valid values are from 0 to 35. If set to 0, soft-delete retention is disabled.
Value for soft-delete retention days for the server such that the server can be restored for the specified number of days after dropping. Only valid values are 0-35. If set to 0, soft-delete retention is disabled.

Copilot uses AI. Check for mistakes.

Administrators :
PrimaryUserAssignedIdentityId :
KeyId :
FederatedClientId :
Copy link
Preview

Copilot AI Sep 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a trailing space after the colon that should be removed for consistency with other output examples.

Suggested change
FederatedClientId :
FederatedClientId :

Copilot uses AI. Check for mistakes.

Comment on lines +61 to +65
bool serverExists = ModelAdapter.ListServers().Any(s =>
string.Equals(s.ResourceGroupName, this.ResourceGroupName, StringComparison.OrdinalIgnoreCase) &&
string.Equals(s.ServerName, this.ServerName, StringComparison.OrdinalIgnoreCase));

if (serverExists)
Copy link
Preview

Copilot AI Sep 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ListServers() call retrieves all servers in the subscription and then filters them in memory. This could be inefficient for subscriptions with many servers. Consider using a more targeted approach like GetServer() with exception handling instead.

Suggested change
bool serverExists = ModelAdapter.ListServers().Any(s =>
string.Equals(s.ResourceGroupName, this.ResourceGroupName, StringComparison.OrdinalIgnoreCase) &&
string.Equals(s.ServerName, this.ServerName, StringComparison.OrdinalIgnoreCase));
if (serverExists)
var server = ModelAdapter.GetServer(this.ResourceGroupName, this.ServerName);
if (server != null)

Copilot uses AI. Check for mistakes.

Comment on lines +210 to +217
if (this.SoftDeleteRetentionDays.HasValue && this.SoftDeleteRetentionDays.Value == 0)
{
updateData[0].SoftDeleteRetentionDays = 0;
}
else
{
updateData[0].SoftDeleteRetentionDays = null;
}
Copy link
Preview

Copilot AI Sep 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The logic for handling SoftDeleteRetentionDays when EnableSoftDeleteRetention is false could be simplified. The nested if-else structure could be replaced with a more direct assignment: updateData[0].SoftDeleteRetentionDays = this.SoftDeleteRetentionDays?.Value == 0 ? 0 : (int?)null;

Suggested change
if (this.SoftDeleteRetentionDays.HasValue && this.SoftDeleteRetentionDays.Value == 0)
{
updateData[0].SoftDeleteRetentionDays = 0;
}
else
{
updateData[0].SoftDeleteRetentionDays = null;
}
updateData[0].SoftDeleteRetentionDays = this.SoftDeleteRetentionDays?.Value == 0 ? 0 : (int?)null;

Copilot uses AI. Check for mistakes.

Copy link
Collaborator

@VeryEarly VeryEarly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Please check in upgraded SDK, under src/Sql/Sql/Management.Sdk
  • Please add proper test cases

}

// SoftDeleteRetentionDays depends on EnableSoftDeleteRetention; if days are provided but soft-delete is not enabled, fail early.
if (this.SoftDeleteRetentionDays.HasValue && this.SoftDeleteRetentionDays > 0 && !this.EnableSoftDeleteRetention)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Should SoftDeleteRetentionDays <= 0 be accepted if EnableSoftDeletionRetention is not supplied or set as false? I ask this purely from a command line user experience behaviour. Should the dependent parameter in absence of its parent always be rejected?

Sid = this.ExternalAdminSID
}
},
SoftDeleteRetentionDays = (this.EnableSoftDeleteRetention && !this.SoftDeleteRetentionDays.HasValue) ? 7 : this.SoftDeleteRetentionDays

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a need to consider logging a message to the terminal that a default value is being taken?

try
{
bool serverExists = ModelAdapter.ListServers().Any(s =>
string.Equals(s.ResourceGroupName, this.ResourceGroupName, StringComparison.OrdinalIgnoreCase) &&

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using ListServersByResourceGroup() API?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or even ModelAdapter.GetServer(ResourceGroupName, ServerName...)

// Now check if there's a deleted server to restore
try
{
var deletedServer = ModelAdapter.GetDeletedServer(this.ResourceGroupName, this.ServerName);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: deletedServer used only once hence can be avoided altogether.

List<Model.AzureSqlServerModel> newEntity = new List<Model.AzureSqlServerModel>();
newEntity.Add(new Model.AzureSqlServerModel()
{
Location = this.Location,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is validation for Location required at this stage of the flow?

throw new PSArgumentException(string.Format(Properties.Resources.ServerNameInvalid, this.ServerName), "ServerName");
}

List<Model.AzureSqlServerModel> newEntity = new List<Model.AzureSqlServerModel>();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can combine into something like

return new List<Model.AzureSqlServerModel>
{
    new Model.AzureSqlServerModel
    {
        Location = this.Location,
        ResourceGroupName = this.ResourceGroupName,
        ServerName = this.ServerName,
        CreateMode = "Restore"
    }
};

/// <returns>The created server</returns>
protected override IEnumerable<Model.AzureSqlServerModel> PersistChanges(IEnumerable<Model.AzureSqlServerModel> entity)
{
return new List<Model.AzureSqlServerModel>() {
Copy link

@pranavathalye pranavathalye Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Assert that entity.Count == 1?

{
// If not enabling, only explicitly set retention to 0 when the caller provided 0.
// Otherwise, leave as null so the service preserves the existing retention setting.
if (this.SoftDeleteRetentionDays.HasValue && this.SoftDeleteRetentionDays.Value == 0)
Copy link

@pranavathalye pranavathalye Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a special case to allow user to reset SoftDeleteRetentionDays to 0, which effectively disables soft delete?

  1. Is changing of retention days via this cmdlet not allowed?
  2. If setting retention to 0 days is used as means to disallow soft deletion -
    2a. How does user enable it back?
    2b. Why not use a parameter DisableSoftDelete or DisableSoftDeleteRetention?

Copy link

@pranavathalye pranavathalye left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completed first review pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants