-
Notifications
You must be signed in to change notification settings - Fork 4k
Nemanjas/mi change hw generation #10892
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nemanjas/mi change hw generation #10892
Conversation
src/Sql/Sql/ChangeLog.md
Outdated
@@ -27,6 +27,7 @@ | |||
## Version 2.1.1 | |||
* Update references in .psd1 to use relative path | |||
* Upgraded storage creation in Vulnerability Assessment auto enablement to StorageV2 | |||
* Adding support for changing existing managed instance hardware generation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sql Managed Instance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
/// </summary> | ||
[Parameter(Mandatory = false, | ||
HelpMessage = "The compute generation for the instance.")] | ||
[ValidateNotNullOrEmpty] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to add custom validators as attributes above fields?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've checked SQL DB, instance pools and managed instance new and set cmdlets and couldn't find the example of that so I decided to go this way. If it is possible, it is not common.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK there is a completer for resource group name, if that exists then it must just be an ARM call so you could also call capabilities to find edition, sku name, compute gen, etc. So probably possible. But let's not block release on it :)
@@ -246,6 +420,7 @@ protected override IEnumerable<AzureSqlManagedInstanceModel> PersistChanges(IEnu | |||
/// </summary> | |||
public override void ExecuteCmdlet() | |||
{ | |||
// System.Diagnostics.Debugger.Launch(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leftover from debugging. Removed.
{ | ||
ModelAdapter = InitModelAdapter(); | ||
AzureSqlManagedInstanceModel existingInstance = ModelAdapter.GetManagedInstance(this.ResourceGroupName, this.Name); | ||
Management.Internal.Resources.Models.Sku Sku = new Management.Internal.Resources.Models.Sku(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch. Thanks. Fixed
|
||
ModelAdapter = InitModelAdapter(); | ||
AzureSqlManagedInstanceModel existingInstance = ModelAdapter.GetManagedInstance(this.ResourceGroupName, this.Name); | ||
Management.Internal.Resources.Models.Sku Sku = new Management.Internal.Resources.Models.Sku(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -290,6 +325,21 @@ Accept pipeline input: True (ByPropertyName) | |||
Accept wildcard characters: False | |||
``` | |||
|
|||
### -SkuName | |||
The SKU name for the instance e.g. 'BC_Gen4'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As Gen4 is becoming deprecated, maybe it's better to have BC_Gen5 here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is much better. Fixed
/// Gets or sets the instance SKU name | ||
/// </summary> | ||
[Parameter(Mandatory = false, | ||
HelpMessage = "The SKU name for the instance e.g. 'GP_Gen4','BC_Gen4'.")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest adding 'GP_Gen5','BC_Gen5' in help message as Gen4 is becoming deprecated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch. Fixed
string computeGeneration = existingInstance.Sku.Name.Contains(Constants.ComputeGenerationGen4) ? Constants.ComputeGenerationGen4 : Constants.ComputeGenerationGen5; | ||
string editionShort = AzureSqlManagedInstanceAdapter.GetInstanceSkuPrefix(Edition); | ||
Sku.Name = editionShort + "_" + computeGeneration; | ||
Sku.Tier = Edition; | ||
Sku.Name = SkuName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not populating Sku.Tier and Sku.Family here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've omitted for brevity because Sku.Name is enough for upsert
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you need to explain in PR, it's worth adding a code comment :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice tip. Thanks for that. Adding comment
string currentEdition = existingInstance.Sku.Tier; | ||
|
||
// Get current hardware family | ||
string currentComputeGeneration = existingInstance.Sku.Name.Contains(Constants.ComputeGenerationGen4) ? Constants.ComputeGenerationGen4 : Constants.ComputeGenerationGen5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these always populated for existing managed instances?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When getting managed instance, Sku.Name is always populated
{ | ||
throw new PSArgumentException( | ||
string.Format(Microsoft.Azure.Commands.Sql.Properties.Resources.InstancePoolInstanceCannotChangeHardwareFamily, this.Name, existingInstance.InstancePoolName), | ||
"Edition"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why all these validations on client side? Isn't server side doing the same validation? Having business logic on the client side is generally a bad idea because PowerShell/CLI is installed on user's machine, so they need to download updates when our policies change - this is really bad experience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed all validation except prompting from confirmation that the changing hardware family is irreversible.
|
||
string edition = null; | ||
|
||
if (skuName.Equals(Constants.GeneralPurposeGen4, StringComparison.InvariantCultureIgnoreCase) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hardcoding of sku names / edition names on client side will add maintenance cost every time a new edition / gen is released. I think we need a different strategy here. For example, in CLI code we use capabilities API to find SKU based on requested parameters. Alternatively, perhaps you can reuse some of the existing edition/sku handling logic from db/elastic pool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed any more since SkuName parameter is removed.
…to nemanjas/mi_change_hw_generation Sync with latest
Adding unit test
…e_hw_generation Merging to the latest.
|
||
[Fact] | ||
[Trait(Category.AcceptanceType, Category.CheckIn)] | ||
public void GetHardwareGenerationFromSkuName() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice to see!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks :)
HelpMessage = "The SKU name for the instance e.g. 'GP_Gen5','BC_Gen5'.")] | ||
[ValidateNotNullOrEmpty] | ||
[PSArgumentCompleter(Constants.GeneralPurposeGen5, Constants.BusinessCriticalGen5)] | ||
public string SkuName { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be a different parameter set than compute&family params.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we discussed offline, we will remove SkuName from parameters.
/// </summary> | ||
[Parameter(Mandatory = false, | ||
HelpMessage = "The compute generation for the instance.")] | ||
[ValidateNotNullOrEmpty] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK there is a completer for resource group name, if that exists then it must just be an ARM call so you could also call capabilities to find edition, sku name, compute gen, etc. So probably possible. But let's not block release on it :)
|
||
bool isHardwareFamilyChanged = !string.IsNullOrWhiteSpace(requestedHardwareFamily) && !currentHardwareFamily.Equals(requestedHardwareFamily, StringComparison.InvariantCultureIgnoreCase); | ||
|
||
// Check whether hardware family is being changed to a deprecated hardware family |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you mean, check whether it's being changed away from a deprecated family?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this code is wrong. Instead of checking if requested == Gen5, it should be checking if current == Gen4. Moving Gen7->Gen5 shouldn't require confirmation, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are absolutely correct. Brilliant catch. Fixing this
string edition = null; | ||
|
||
if (skuName.Equals(Constants.GeneralPurposeGen4, StringComparison.InvariantCultureIgnoreCase) | ||
|| skuName.Equals(Constants.GeneralPurposeGen5, StringComparison.InvariantCultureIgnoreCase)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you just check StartsWith("GP_") or StartsWith("BC_"), instead of having every combination programmed ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even better would be if you implemented a function which is the opposite of GetInstanceSkuPrefix()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, this method is also redundant. I'll remove it
string currentEdition = existingInstance.Sku.Tier; | ||
|
||
// Get current hardware family | ||
string currentComputeGeneration = existingInstance.Sku.Name.Contains(Constants.ComputeGenerationGen4) ? Constants.ComputeGenerationGen4 : Constants.ComputeGenerationGen5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it would cause problems when next compute gen is released. Please distinguish between Gen4, Gen5, and "unknown"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will use SqlSkuUtils.GetHardwareGenerationFromSkuName instead this if.
string computeGeneration = existingInstance.Sku.Name.Contains(Constants.ComputeGenerationGen4) ? Constants.ComputeGenerationGen4 : Constants.ComputeGenerationGen5; | ||
string editionShort = AzureSqlManagedInstanceAdapter.GetInstanceSkuPrefix(Edition); | ||
Sku.Name = editionShort + "_" + computeGeneration; | ||
Sku.Tier = Edition; | ||
Sku.Name = SkuName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you need to explain in PR, it's worth adding a code comment :)
/// Get hardware family from SKU name. | ||
/// </summary> | ||
/// <returns>The model to send to the update</returns> | ||
public static string GetHardwareGenerationFromSkuName(string skuName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider moving to SqlSkuUtils.cs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that, in order to run unit tests, SqlSkuUtils had to be changed to public
<value>Do you want to proceed?</value> | ||
</data> | ||
<data name="ChangingHardwareFamilyIsIrreversable" xml:space="preserve"> | ||
<value>For this update operation provided compute generation parameter is Gen5. Once the hardware generation is upgraded, it is not possible to switch back to Gen4 compute generation as this hardware is being deprecated.</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This message will not be accurate when next gen is released and you upgrade Gen4->Gen7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to fill it in dinamically
<value>You cannot change hardware family.</value> | ||
</data> | ||
<data name="InvalidManagedInstanceSkuName" xml:space="preserve"> | ||
<value>Provided SkuName '{0}' is invalid '{1}'. Please enter a valid SkuName value and execute command again.</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to give example sku name so that customer has an better idea of what we're asking for
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This message is no longer needed. Removing it.
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
src/Sql/Sql/ChangeLog.md
Outdated
@@ -31,6 +31,7 @@ Fix New-AzSqlDatabaseSecondary cmdlet to check for PartnerDatabaseName existence | |||
## Version 2.1.1 | |||
* Update references in .psd1 to use relative path | |||
* Upgraded storage creation in Vulnerability Assessment auto enablement to StorageV2 | |||
* Adding support for changing existing Sql Managed Instance hardware generation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes for the upcoming release should go under the section titled "Upcoming Release".
Hi @v-nestan please fix the problem in Changelog.md . Besides, in order for CI to be triggered, please join Azure orgnization: https://aka.ms/AzureGithub thanks |
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
…neration Nemanjas/mi change hw generation
Description
This change adds support for changing existing managed instance hardware generation.
It can be changed using SkuName and ComputeGeneration parameters.
TFS item link
Checklist
CONTRIBUTING.md
ChangeLog.md
file(s) has been updated:ChangeLog.md
file can be found atsrc/{{SERVICE}}/{{SERVICE}}/ChangeLog.md
## Upcoming Release
header -- no new version header should be added