Skip to content

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

Merged
merged 13 commits into from
Feb 4, 2020

Conversation

v-nestan
Copy link
Contributor

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

  • I have read the Submitting Changes section of CONTRIBUTING.md
  • The title of the PR is clear and informative
  • The appropriate ChangeLog.md file(s) has been updated:
    • For any service, the ChangeLog.md file can be found at src/{{SERVICE}}/{{SERVICE}}/ChangeLog.md
    • A snippet outlining the change(s) made in the PR should be written under the ## Upcoming Release header -- no new version header should be added
  • The PR does not introduce breaking changes
  • If applicable, the changes made in the PR have proper test coverage
  • For public API changes to cmdlets:
    • a cmdlet design review was approved for the changes in this repository (Microsoft internal only)
    • the markdown help files have been regenerated using the commands listed here

@@ -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
Copy link
Contributor

Choose a reason for hiding this comment

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

Sql Managed Instance

Copy link
Contributor Author

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]
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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 :)

@v-nestan v-nestan requested a review from cormacpayne January 14, 2020 17:40
@@ -246,6 +420,7 @@ protected override IEnumerable<AzureSqlManagedInstanceModel> PersistChanges(IEnu
/// </summary>
public override void ExecuteCmdlet()
{
// System.Diagnostics.Debugger.Launch();
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove this

Copy link
Contributor Author

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();
Copy link
Contributor

Choose a reason for hiding this comment

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

Not used

Copy link
Contributor Author

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();
Copy link
Contributor

Choose a reason for hiding this comment

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

Not used

Copy link
Contributor Author

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'.
Copy link
Contributor

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

Copy link
Contributor Author

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'.")]
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch. Fixed

Comment on lines 202 to 372
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;
Copy link
Contributor

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?

Copy link
Contributor Author

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

Copy link
Contributor

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 :)

Copy link
Contributor Author

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

Comment on lines 365 to 368
string currentEdition = existingInstance.Sku.Tier;

// Get current hardware family
string currentComputeGeneration = existingInstance.Sku.Name.Contains(Constants.ComputeGenerationGen4) ? Constants.ComputeGenerationGen4 : Constants.ComputeGenerationGen5;
Copy link
Contributor

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?

Copy link
Contributor Author

@v-nestan v-nestan Jan 15, 2020

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");
Copy link
Contributor

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.

Copy link
Contributor Author

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)
Copy link
Contributor

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.

Copy link
Contributor Author

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.

@isra-fel isra-fel self-assigned this Jan 15, 2020
Nemanja added 2 commits January 15, 2020 18:58
…to nemanjas/mi_change_hw_generation

Sync with latest
Adding unit test

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void GetHardwareGenerationFromSkuName()
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice to see!

Copy link
Contributor Author

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; }
Copy link
Contributor

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.

Copy link
Contributor Author

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]
Copy link
Contributor

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
Copy link
Contributor

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?

Copy link
Contributor

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?

Copy link
Contributor Author

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))
Copy link
Contributor

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 ?

Copy link
Contributor

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()

Copy link
Contributor Author

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;
Copy link
Contributor

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"

Copy link
Contributor Author

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.

Comment on lines 202 to 372
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;
Copy link
Contributor

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)
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor Author

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>
Copy link
Contributor

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

Copy link
Contributor Author

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>
Copy link
Contributor

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

Copy link
Contributor Author

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.

jaredmoo
jaredmoo previously approved these changes Jan 31, 2020
@isra-fel
Copy link
Member

isra-fel commented Feb 3, 2020

/azp run

@azure-pipelines
Copy link
Contributor

Azure Pipelines successfully started running 3 pipeline(s).

@isra-fel isra-fel assigned isra-fel and unassigned v-nestan Feb 3, 2020
jaredmoo
jaredmoo previously approved these changes Feb 3, 2020
@isra-fel
Copy link
Member

isra-fel commented Feb 4, 2020

/azp run

@azure-pipelines
Copy link
Contributor

Azure Pipelines successfully started running 3 pipeline(s).

@@ -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
Copy link
Member

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".

@isra-fel
Copy link
Member

isra-fel commented Feb 4, 2020

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

@isra-fel isra-fel assigned v-nestan and unassigned isra-fel Feb 4, 2020
@isra-fel
Copy link
Member

isra-fel commented Feb 4, 2020

/azp run

@azure-pipelines
Copy link
Contributor

Azure Pipelines successfully started running 3 pipeline(s).

@isra-fel isra-fel merged commit 940d05c into Azure:master Feb 4, 2020
dingmeng-xue pushed a commit to dingmeng-xue/azure-powershell that referenced this pull request Mar 29, 2020
…neration

Nemanjas/mi change hw generation
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.

5 participants