Removing SQL Legacy usage for FirewallRules#29465
Conversation
| Thanks for your contribution! The pull request validation has started. Please revisit this comment for updated status. |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
This pull request removes legacy (2014-era) SQL Firewall Rule implementation usage by switching the cmdlets’ internal plumbing to the current Microsoft.Azure.Management.Sql SDK surface, and regenerating the Sql management SDK to include FirewallRules operations.
Changes:
- Updated Firewall Rule communicator/adapter to use
Microsoft.Azure.Management.Sqlmodels/operations instead ofLegacySdk. - Added paging-aware listing for server firewall rules using
ListByServer+ListByServerNext. - Regenerated
Sql.Management.Sdkto includeIFirewallRulesOperationsand related models/operations, and updated the generation README inputs.
Reviewed changes
Copilot reviewed 4 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Sql/Sql/FirewallRule/Services/AzureSqlServerFirewallRuleCommunicator.cs | Swaps legacy client/model usage for new SDK operations; adds manual paging for list. |
| src/Sql/Sql/FirewallRule/Services/AzureSqlServerFirewallRuleAdapter.cs | Updates adapter mapping and upsert payload to new SDK FirewallRule shape. |
| src/Sql/Sql/ChangeLog.md | Adds release note entry for removal of legacy 2014 API usage in firewall rule cmdlets. |
| src/Sql/Sql.Management.Sdk/README.md | Updates AutoRest input specs/commit and includes FirewallRules spec. |
| src/Sql/Sql.Management.Sdk/Generated/SqlManagementClient.cs | Adds FirewallRules operations property initialization. |
| src/Sql/Sql.Management.Sdk/Generated/Models/ServerFirewallRuleProperties.cs | New generated model type for firewall rule properties. |
| src/Sql/Sql.Management.Sdk/Generated/Models/FirewallRuleList.cs | New generated list wrapper model. |
| src/Sql/Sql.Management.Sdk/Generated/Models/FirewallRule.cs | New generated firewall rule resource model. |
| src/Sql/Sql.Management.Sdk/Generated/ISqlManagementClient.cs | Exposes IFirewallRulesOperations on the client interface. |
| src/Sql/Sql.Management.Sdk/Generated/IFirewallRulesOperations.cs | New generated operations interface for firewall rules. |
| src/Sql/Sql.Management.Sdk/Generated/FirewallRulesOperationsExtensions.cs | New generated extension methods for firewall rules operations. |
| src/Sql/Sql.Management.Sdk/Generated/FirewallRulesOperations.cs | New generated implementation for firewall rules REST operations. |
|
|
||
| var pagedResponse = GetCurrentSqlClient().FirewallRules.ListByServer(resourceGroupName, serverName); | ||
| resultsList.AddRange(pagedResponse); | ||
|
|
||
| while (!string.IsNullOrEmpty(pagedResponse.NextPageLink)) | ||
| { | ||
| pagedResponse = GetCurrentSqlClient().FirewallRules.ListByServerNext(pagedResponse.NextPageLink); |
There was a problem hiding this comment.
List() repeatedly calls GetCurrentSqlClient() (including inside the pagination loop), which creates a new SqlManagementClient each time. This adds avoidable overhead and could cause inconsistent per-invocation settings/headers. Consider creating the client once at the start of List() and reusing it for the initial call and subsequent ListByServerNext() calls.
| var pagedResponse = GetCurrentSqlClient().FirewallRules.ListByServer(resourceGroupName, serverName); | |
| resultsList.AddRange(pagedResponse); | |
| while (!string.IsNullOrEmpty(pagedResponse.NextPageLink)) | |
| { | |
| pagedResponse = GetCurrentSqlClient().FirewallRules.ListByServerNext(pagedResponse.NextPageLink); | |
| var sqlClient = GetCurrentSqlClient(); | |
| var pagedResponse = sqlClient.FirewallRules.ListByServer(resourceGroupName, serverName); | |
| resultsList.AddRange(pagedResponse); | |
| while (!string.IsNullOrEmpty(pagedResponse.NextPageLink)) | |
| { | |
| pagedResponse = sqlClient.FirewallRules.ListByServerNext(pagedResponse.NextPageLink); |
| private SqlManagementClient GetCurrentSqlClient(string subscriptionId = null) | ||
| { | ||
| // Get the SQL management client for the current subscription | ||
| if (SqlClient == null) | ||
| // Note: client is not cached in static field because that causes ObjectDisposedException in functional tests. | ||
| var sqlClient = AzureSession.Instance.ClientFactory.CreateArmClient<Management.Sql.SqlManagementClient>(Context, AzureEnvironment.Endpoint.ResourceManager); | ||
| if (subscriptionId != null) | ||
| { | ||
| SqlClient = AzureSession.Instance.ClientFactory.CreateClient<SqlManagementClient>(Context, AzureEnvironment.Endpoint.ResourceManager); | ||
| sqlClient.SubscriptionId = subscriptionId; | ||
| } | ||
| return SqlClient; | ||
| return sqlClient; |
There was a problem hiding this comment.
GetCurrentSqlClient no longer uses the static SqlClient cache, but the class still keeps SqlClient/Subscription static state and resets SqlClient in the constructor. This state is now unused and can mislead future changes; either remove the static fields/subscription-switch logic or reintroduce caching in a safe way.
| private SqlManagementClient GetCurrentSqlClient(string subscriptionId = null) | ||
| { | ||
| // Get the SQL management client for the current subscription | ||
| if (SqlClient == null) | ||
| // Note: client is not cached in static field because that causes ObjectDisposedException in functional tests. | ||
| var sqlClient = AzureSession.Instance.ClientFactory.CreateArmClient<Management.Sql.SqlManagementClient>(Context, AzureEnvironment.Endpoint.ResourceManager); | ||
| if (subscriptionId != null) | ||
| { | ||
| SqlClient = AzureSession.Instance.ClientFactory.CreateClient<SqlManagementClient>(Context, AzureEnvironment.Endpoint.ResourceManager); | ||
| sqlClient.SubscriptionId = subscriptionId; | ||
| } |
There was a problem hiding this comment.
GetCurrentSqlClient takes an optional subscriptionId parameter, but the method is private and this class only calls it without arguments. If the parameter isn’t needed, remove it to reduce confusion; otherwise add a call site that passes the intended subscription id (or document why the override is required).
| /// Convert a Management.Sql.LegacySdk.Models.FirewallRule to AzureSqlServerFirewallRuleModel | ||
| /// </summary> | ||
| /// <param name="resourceGroup">The resource group the server is in</param> | ||
| /// <param name="serverName">The name of the server</param> | ||
| /// <param name="resp">The management client server response to convert</param> | ||
| /// <returns>The converted server model</returns> | ||
| private static AzureSqlServerFirewallRuleModel CreateFirewallRuleModelFromResponse(string resourceGroup, string serverName, Management.Sql.LegacySdk.Models.FirewallRule resp) | ||
| private static AzureSqlServerFirewallRuleModel CreateFirewallRuleModelFromResponse(string resourceGroup, string serverName, Management.Sql.Models.FirewallRule resp) | ||
| { |
There was a problem hiding this comment.
The XML doc comment still says it converts a Management.Sql.LegacySdk.Models.FirewallRule, but the method now accepts Management.Sql.Models.FirewallRule. Please update the comment to match the new SDK type to avoid misleading documentation.
| public IList<Management.Sql.Models.FirewallRule> List(string resourceGroupName, string serverName) | ||
| { | ||
| return GetCurrentSqlClient().FirewallRules.List(resourceGroupName, serverName).FirewallRules; | ||
| List<Management.Sql.Models.FirewallRule> resultsList = new List<Management.Sql.Models.FirewallRule>(); | ||
|
|
||
| var pagedResponse = GetCurrentSqlClient().FirewallRules.ListByServer(resourceGroupName, serverName); | ||
| resultsList.AddRange(pagedResponse); | ||
|
|
||
| while (!string.IsNullOrEmpty(pagedResponse.NextPageLink)) | ||
| { | ||
| pagedResponse = GetCurrentSqlClient().FirewallRules.ListByServerNext(pagedResponse.NextPageLink); | ||
| resultsList.AddRange(pagedResponse); | ||
| } |
There was a problem hiding this comment.
The new paging logic in List() is currently untested in this module’s test suite. Since Get-AzSqlServerFirewallRule depends on List(), consider adding/expanding scenario coverage for firewall rule CRUD (including list pagination via NextPageLink) similar to the existing IPv6 firewall rule scenario tests.
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
| using Hyak.Common; | ||
| using Microsoft.Azure.Management.Sql.Models; | ||
| using System.Collections.Generic; | ||
| using System.Linq; |
There was a problem hiding this comment.
using Hyak.Common; is now unused after switching the exception type to ErrorResponseException. With warnings treated as errors in this repo, the unused using can break the build; please remove it (or use CloudException again if intended).
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
Description
Removing legacy usage of 2014 APIs from SQL
Mandatory Checklist
Please choose the target release of Azure PowerShell. (⚠️ Target release is a different concept from API readiness. Please click below links for details.)
Check this box to confirm: I have read the Submitting Changes section of
CONTRIBUTING.mdand reviewed the following information:ChangeLog.mdfile(s) appropriatelysrc/{{SERVICE}}/{{SERVICE}}/ChangeLog.md.## Upcoming Releaseheader in the past tense.ChangeLog.mdif no new release is required, such as fixing test case only.