Skip to content
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

Migrate Restore-AzStorageBlobRange and ManagementPolicy related cmdlets #14

Merged
merged 12 commits into from
Jun 10, 2022
10 changes: 9 additions & 1 deletion src/Storage/Storage.Management/Models/PSBlobRestore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public PSBlobRestoreRange(Track2Models.BlobRestoreRange range)
foreach (PSBlobRestoreRange range in ranges)
{
re.Add(
new Track2Models.BlobRestoreRange(range.EndRange, range.StartRange));
new Track2Models.BlobRestoreRange(range.StartRange, range.EndRange));
}
}
return re;
Expand Down Expand Up @@ -112,6 +112,14 @@ public PSBlobRestoreStatus(Track2Models.BlobRestoreStatus status)
this.Parameters = status.Parameters is null ? null : new PSBlobRestoreParameters(status.Parameters);
}
}

public PSBlobRestoreStatus(string status, string failureReason, string restoreId, PSBlobRestoreParameters parameters)
{
Status = status;
FailureReason = failureReason;
RestoreId = restoreId;
Parameters = parameters;
}
}

/// <summary>
Expand Down
197 changes: 108 additions & 89 deletions src/Storage/Storage.Management/Models/PSDataPolicy.cs

Large diffs are not rendered by default.

9 changes: 0 additions & 9 deletions src/Storage/Storage.Management/Storage.Management.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,6 @@
<AssemblyName>$(AzAssemblyPrefix)$(PsModuleName).Management</AssemblyName>
<RootNamespace>$(LegacyAssemblyPrefix)$(PsModuleName)</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Remove="StorageAccount\AddAzureStorageAccountNetworkRule.cs" />
<Compile Remove="StorageAccount\GetAzureStorageAccountNetworkRuleSet.cs" />
<Compile Remove="StorageAccount\InvokeAzureStorageAccountFailover.cs" />
<Compile Remove="StorageAccount\InvokeAzureStorageAccountHierarchicalNamespaceUpgrade.cs" />
<Compile Remove="StorageAccount\RemoveAzureStorageAccountNetworkRule.cs" />
<Compile Remove="StorageAccount\RestoreAzStorageBlobRange.cs" />
<Compile Remove="StorageAccount\UpdateAzureStorageAccountNetworkRuleSet.cs" />
</ItemGroup>
<ItemGroup>
<!-- <PackageReference Include="Azure.Core" Version="1.24.0" /> -->
<PackageReference Include="Azure.ResourceManager" Version="1.0.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

using Microsoft.Azure.Commands.Management.Storage.Models;
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
using Microsoft.Azure.Management.Storage;
using Microsoft.Azure.Management.Storage.Models;
using Microsoft.WindowsAzure.Commands.Common.CustomAttributes;
using System.Globalization;
using System.Management.Automation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@
// limitations under the License.
// ----------------------------------------------------------------------------------

using Azure.ResourceManager.Storage;
using Microsoft.Azure.Commands.Management.Storage.Models;
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
using Microsoft.Azure.Management.Storage;
using Microsoft.Azure.Management.Storage.Models;
using Microsoft.WindowsAzure.Commands.Common.CustomAttributes;
using System.Management.Automation;

Expand Down Expand Up @@ -95,11 +94,11 @@ public override void ExecuteCmdlet()
break;
}

ManagementPolicy managementPolicy = this.StorageClient.ManagementPolicies.Get(
this.ResourceGroupName,
this.StorageAccountName);
ManagementPolicyResource policy = this.StorageClientTrack2.GetManagementPolicyResource(
this.ResourceGroupName, this.StorageAccountName, "default").Get();

WriteObject(new PSManagementPolicy(managementPolicy, this.ResourceGroupName, this.StorageAccountName), true);
var result = new PSManagementPolicy(policy, this.ResourceGroupName, this.StorageAccountName);
WriteObject(result, true);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

using Microsoft.Azure.Commands.Management.Storage.Models;
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
using Microsoft.Azure.Management.Storage;
using Microsoft.Azure.Management.Storage.Models;
using System.Management.Automation;

namespace Microsoft.Azure.Commands.Management.Storage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

using Microsoft.Azure.Commands.Management.Storage.Models;
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
using Microsoft.Azure.Management.Storage;
using Microsoft.Azure.Management.Storage.Models;
using Microsoft.WindowsAzure.Commands.Common.CustomAttributes;
using System.Management.Automation;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@
// limitations under the License.
// ----------------------------------------------------------------------------------

using Azure;
using Microsoft.Azure.Commands.Management.Storage.Models;
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
using Microsoft.Azure.Management.Storage;
using Microsoft.Azure.Management.Storage.Models;
using System.Management.Automation;

namespace Microsoft.Azure.Commands.Management.Storage
Expand Down Expand Up @@ -116,9 +115,8 @@ public override void ExecuteCmdlet()
break;
}

this.StorageClient.ManagementPolicies.Delete(
this.ResourceGroupName,
this.StorageAccountName);
this.StorageClientTrack2.GetManagementPolicyResource(this.ResourceGroupName, this.StorageAccountName, "default")
.Delete(WaitUntil.Completed);

if (PassThru.IsPresent)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@
// limitations under the License.
// ----------------------------------------------------------------------------------

using Azure;
using Microsoft.Azure.Commands.Management.Storage.Models;
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
using Microsoft.Azure.Management.Storage;
using Microsoft.Azure.Management.Storage.Models;
using Microsoft.Rest.Azure;
using Microsoft.WindowsAzure.Commands.Utilities.Common;
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Threading.Tasks;
using Track2 = Azure.ResourceManager.Storage;
using Track2Models = Azure.ResourceManager.Storage.Models;

namespace Microsoft.Azure.Commands.Management.Storage
{
Expand Down Expand Up @@ -79,7 +82,7 @@ public class RestoreAzureStorageBlobRangeCommand : StorageAccountBaseCmdlet

[Parameter(Mandatory = true, HelpMessage = "The Time to Restore Blob.")]
[ValidateNotNull]
public DateTime TimeToRestore { get; set; }
public DateTimeOffset TimeToRestore { get; set; }

[Parameter(Mandatory = false, HelpMessage = "The blob range to Restore.")]
[ValidateNotNull]
Expand Down Expand Up @@ -119,47 +122,95 @@ public override void ExecuteCmdlet()
if (ShouldProcess(this.StorageAccountName, "Restore Blob Range"))
{
if (waitForComplete)
{
Task<AzureOperationResponse<BlobRestoreStatus>> beginTask = this.StorageClient.StorageAccounts.BeginRestoreBlobRangesWithHttpMessagesAsync(
this.ResourceGroupName,
this.StorageAccountName,
this.TimeToRestore,
PSBlobRestoreRange.ParseBlobRestoreRanges(this.BlobRestoreRange));

beginTask.Wait();

AzureOperationResponse<BlobRestoreStatus> response = beginTask.Result;

WriteWarning(string.Format("Restore blob ranges with Id '{0}' started. Restore blob ranges time to complete is dependent on the size of the restore.", response.Body is null ? "" : response.Body.RestoreId));
{
Track2.StorageAccountResource account = this.StorageClientTrack2.GetStorageAccount(this.ResourceGroupName, this.StorageAccountName);
var restoreLro = account.RestoreBlobRanges(
WaitUntil.Started,
new Track2Models.BlobRestoreContent(
this.TimeToRestore,
PSBlobRestoreRange.ParseBlobRestoreRanges(this.BlobRestoreRange))
);

Dictionary<string, object> temp = restoreLro.GetRawResponse().Content.ToObjectFromJson() as Dictionary<string, object>;
object restoreId;

if (temp != null && temp.TryGetValue("restoreId", out restoreId))
Copy link
Member

Choose a reason for hiding this comment

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

We may return early when this condition is hit, otherwise all the places using temp.*** need a null-check.

Copy link
Author

Choose a reason for hiding this comment

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

Discussed offline with Wei and changed to throw an exception when temp is null. Thus temp referenced below is definitely not null.
Getting the raw response is a temporary workaround for this SDK issue. We will remove this chunk of code once the issue is fixed, and we should be able to get BlobRestoreStatus object directly with the SDK.

{
WriteWarning(string.Format("Restore blob ranges with Id '{0}' started. Restore blob ranges time to complete is dependent on the size of the restore.", restoreId));
}
else
{
WriteWarning(string.Format("Could not fetch the Restore Id."));
}

Task<AzureOperationResponse<BlobRestoreStatus>> waitTask = ((StorageManagementClient)this.StorageClient).GetPostOrDeleteOperationResultAsync(response, null, new System.Threading.CancellationToken());
try
{
waitTask.Wait();
var result = restoreLro.WaitForCompletion().Value;
WriteObject(new PSBlobRestoreStatus(result));
}
catch (System.AggregateException ex) when (ex.InnerException is CloudException)
{
throw new InvalidJobStateException(string.Format("Blob ranges restore failed with information: '{0}'.", ((CloudException)ex.InnerException).Response.Content));
throw new InvalidJobStateException(string.Format("Blob ranges restore failed with information: '{0}'.", ex.ToString()));
}

AzureOperationResponse<BlobRestoreStatus> result = waitTask.Result;

WriteObject(new PSBlobRestoreStatus(result.Body));

}
else
{
BlobRestoreStatus status = this.StorageClient.StorageAccounts.BeginRestoreBlobRanges(
this.ResourceGroupName,
this.StorageAccountName,
this.TimeToRestore,
PSBlobRestoreRange.ParseBlobRestoreRanges(this.BlobRestoreRange));

WriteObject(new PSBlobRestoreStatus(status));
if (status != null && status.Status == BlobRestoreProgressStatus.Failed)
Track2.StorageAccountResource account = this.StorageClientTrack2.GetStorageAccount(this.ResourceGroupName, this.StorageAccountName);
var restoreLro = account.RestoreBlobRanges(
WaitUntil.Started,
new Track2Models.BlobRestoreContent(
this.TimeToRestore.ToUniversalTime(),
PSBlobRestoreRange.ParseBlobRestoreRanges(this.BlobRestoreRange)));
Dictionary<string, object> temp = restoreLro.GetRawResponse().Content.ToObjectFromJson() as Dictionary<string, object>;
object jobStatus = null;

if (temp != null && temp.TryGetValue("status", out jobStatus))
{
if (jobStatus != null && jobStatus.ToString() == Track2Models.BlobRestoreProgressStatus.Failed.ToString())
{
throw new InvalidJobStateException("Blob ranges restore failed.");
}
} else
{
throw new InvalidJobStateException("Blob ranges restore failed.");
WriteWarning(string.Format("Could not fetch the status."));
}

temp.TryGetValue("restoreId", out object restoreId);
Copy link
Member

Choose a reason for hiding this comment

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

temp.*** is not guarded by the null-check.

Copy link
Author

Choose a reason for hiding this comment

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

Changed to throw an exception when temp is null

temp.TryGetValue("parameters", out object parameters);

PSBlobRestoreParameters blobRestoreParameters = new PSBlobRestoreParameters();
Dictionary<string, object> paramMap = parameters as Dictionary<string, object>;

paramMap.TryGetValue("timetoRestore", out object timeToRestore);
Copy link
Member

@yaxia yaxia Jun 8, 2022

Choose a reason for hiding this comment

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

paramMap

could paraMap be null? #Closed

Copy link
Author

Choose a reason for hiding this comment

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

Fixed. Assign null to blobRestoreParameters when paramMap is null

Copy link
Member

@yaxia yaxia Jun 8, 2022

Choose a reason for hiding this comment

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

timetoRestore

is this case sensitive? Should it be timeToRestore?

Copy link
Author

Choose a reason for hiding this comment

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

Double checked the response. Weird but it's timetoRestore (might be a typo on the server side?), so I'm keeping timetoRestore here.

DateTimeOffset.TryParse(timeToRestore.ToString(), out DateTimeOffset parseDate);
Copy link
Member

@yaxia yaxia Jun 8, 2022

Choose a reason for hiding this comment

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

timeToRestore

When paramMap.TryGetValue fails (e.g.: there is no "timetoRestore" field), the object is null. #Closed

Copy link
Author

Choose a reason for hiding this comment

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

Fixed

blobRestoreParameters.TimeToRestore = parseDate;

paramMap.TryGetValue("blobRanges", out object ranges);
List<PSBlobRestoreRange> blobRestoreRanges = new List<PSBlobRestoreRange>();

object[] rangesList = ranges as object[];
foreach(object range in rangesList)
{
Dictionary<string, object> rangeMap = range as Dictionary<string, object>;

rangeMap.TryGetValue("startRange", out object startRange);
rangeMap.TryGetValue("endRange", out object endRange);

PSBlobRestoreRange blobRestoreRange = new PSBlobRestoreRange
{
StartRange = startRange == null ? null : startRange.ToString(),
Copy link
Member

@yaxia yaxia Jun 6, 2022

Choose a reason for hiding this comment

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

startRange?.ToString() #Closed

Copy link
Member

Choose a reason for hiding this comment

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

same comment to the below

Copy link
Author

Choose a reason for hiding this comment

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

Done

EndRange = endRange == null ? null : endRange.ToString()
};

blobRestoreRanges.Add(blobRestoreRange);
}
blobRestoreParameters.BlobRanges = blobRestoreRanges.ToArray();

WriteObject(new PSBlobRestoreStatus(
status: jobStatus == null ? null : jobStatus.ToString(),
failureReason: null,
restoreId: restoreId == null ? null : restoreId.ToString(),
blobRestoreParameters));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
// limitations under the License.
// ----------------------------------------------------------------------------------

using Azure.ResourceManager.Storage;
using Microsoft.Azure.Commands.Management.Storage.Models;
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
using Microsoft.Azure.Management.Storage;
using Microsoft.Azure.Management.Storage.Models;
using System.Management.Automation;
using Newtonsoft.Json.Linq;
using System.Globalization;
using System.Collections.Generic;
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
using Microsoft.WindowsAzure.Commands.Common.CustomAttributes;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Management.Automation;
using Track2 = Azure.ResourceManager.Storage;

namespace Microsoft.Azure.Commands.Management.Storage
{
Expand Down Expand Up @@ -62,7 +62,7 @@ public class SetAzureStorageAccountManagementPolicyCommand : StorageAccountBaseC
Position = 0,
Mandatory = true,
HelpMessage = "Resource Group Name.",
ParameterSetName = AccountNamePolicyRuleParameterSet)]
ParameterSetName = AccountNamePolicyRuleParameterSet)]
[Parameter(
Position = 0,
Mandatory = true,
Expand Down Expand Up @@ -155,7 +155,7 @@ public override void ExecuteCmdlet()
base.ExecuteCmdlet();
if (ShouldProcess(this.StorageAccountName, "Set Storage Account Management Policy"))
{
if ((this.ParameterSetName == AccountObjectPolicyRuleParameterSet)
if ((this.ParameterSetName == AccountObjectPolicyRuleParameterSet)
|| (this.ParameterSetName == AccountObjectPolicyObjectParameterSet))
{
this.ResourceGroupName = StorageAccount.ResourceGroupName;
Expand All @@ -168,35 +168,43 @@ public override void ExecuteCmdlet()
this.ResourceGroupName = accountResource.ResourceGroupName;
this.StorageAccountName = accountResource.ResourceName;
}
ManagementPolicy managementPolicy;

ManagementPolicyResource managementPolicyResource;
Track2.ManagementPolicyData data;

switch (this.ParameterSetName)
{
case AccountObjectPolicyRuleParameterSet:
case AccountNamePolicyRuleParameterSet:
case AccountResourceIdPolicyRuleParameterSet:
managementPolicy = this.StorageClient.ManagementPolicies.CreateOrUpdate(
this.ResourceGroupName,
this.StorageAccountName,
new ManagementPolicySchema(
//this.version,
PSManagementPolicyRule.ParseManagementPolicyRules(this.Rule)));

data = new Track2.ManagementPolicyData
{
Rules = PSManagementPolicyRule.ParseManagementPolicyRules(this.Rule)
};

managementPolicyResource = this.StorageClientTrack2
.GetManagementPolicyResource(this.ResourceGroupName, this.StorageAccountName, "default")
.CreateOrUpdate(global::Azure.WaitUntil.Completed, data).Value;
break;
case AccountObjectPolicyObjectParameterSet:
case AccountNamePolicyObjectParameterSet:
case AccountResourceIdPolicyObjectParameterSet:
managementPolicy = this.StorageClient.ManagementPolicies.CreateOrUpdate(
this.ResourceGroupName,
this.StorageAccountName,
new ManagementPolicySchema(
//this.Policy.Version,
PSManagementPolicyRule.ParseManagementPolicyRules(this.Policy.Rules)));

data = new Track2.ManagementPolicyData()
{
Rules = PSManagementPolicyRule.ParseManagementPolicyRules(this.Policy.Rules)
};

managementPolicyResource = this.StorageClientTrack2
.GetManagementPolicyResource(this.ResourceGroupName, this.StorageAccountName, "default")
.CreateOrUpdate(global::Azure.WaitUntil.Completed, data).Value;
break;
default:
throw new PSArgumentException(string.Format(CultureInfo.InvariantCulture, "Invalid ParameterSet: {0}", this.ParameterSetName));
}

WriteObject(new PSManagementPolicy(managementPolicy, this.ResourceGroupName, this.StorageAccountName), true);
WriteObject(new PSManagementPolicy(managementPolicyResource, this.ResourceGroupName, this.StorageAccountName), true);
}
}
}
Expand Down
Loading