Skip to content

Commit

Permalink
Enhancement: handle multiple resource groups in one AMS account (#172)
Browse files Browse the repository at this point in the history
* Enhancement:handle multiple resource groups in one AMS account

* update

* address comments

* update

* updates

* update
  • Loading branch information
melindawangmsft authored Sep 8, 2023
1 parent 4f70f9a commit 1a70d8c
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 12 deletions.
2 changes: 1 addition & 1 deletion ams/AssetAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public override async Task MigrateAsync(CancellationToken cancellationToken)
reportGenerator = new ReportGenerator(file);
reportGenerator.WriteHeader();
}
await _resourceProvider.SetStorageResourceGroupsAsync(account, cancellationToken);
var assets = account.GetMediaAssets()
.GetAllAsync(resourceFilter, cancellationToken: cancellationToken);
var statistics = new AssetStats();
Expand All @@ -139,7 +140,6 @@ public override async Task MigrateAsync(CancellationToken cancellationToken)
await MigrateInParallel(assets, filteredList, async (asset, cancellationToken) =>
{
var storage = await _resourceProvider.GetStorageAccountAsync(account, asset, cancellationToken);
var result = await AnalyzeAsync(asset, storage, cancellationToken);
var assetType = result.AssetType ?? "unknown";
assetTypes.AddOrUpdate(assetType, 1, (key, value) => Interlocked.Increment(ref value));
Expand Down
7 changes: 5 additions & 2 deletions ams/AssetMigrator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ public override async Task MigrateAsync(CancellationToken cancellationToken)
_options.CreationTimeEnd);

var orderBy = "properties/created";
var assets = account.GetMediaAssets()
.GetAllAsync(resourceFilter, orderby: orderBy, cancellationToken: cancellationToken);

await _resourceProvider.SetStorageResourceGroupsAsync(account, cancellationToken);
var assets = account.GetMediaAssets().GetAllAsync(resourceFilter, orderby: orderBy, cancellationToken: cancellationToken);

List<MediaAssetResource>? filteredList = null;

Expand Down Expand Up @@ -82,9 +83,11 @@ private async Task<AssetStats> MigrateAsync(MediaServicesAccountResource account
await MigrateInParallel(assets, filteredList, async (asset, cancellationToken) =>
{
var storage = await _resourceProvider.GetStorageAccountAsync(account, asset, cancellationToken);
var result = await MigrateAsync(account, storage, asset, cancellationToken);
stats.Update(result);
await writer.WriteAsync(stats.Total, cancellationToken);
},
_options.BatchSize,
cancellationToken);
Expand Down
50 changes: 44 additions & 6 deletions ams/AzureResourceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
using AMSMigrate.Contracts;
using Azure.Core;
using Azure.ResourceManager;
using Azure.ResourceManager.Storage;
using Azure.ResourceManager.Media;
using Azure.ResourceManager.Media.Models;
using Azure.ResourceManager.Resources;
using Azure.ResourceManager.Storage;
using Azure.Storage.Blobs;

namespace AMSMigrate.Ams
Expand All @@ -14,35 +15,72 @@ class AzureResourceProvider
protected readonly ResourceGroupResource _resourceGroup;
protected readonly GlobalOptions _globalOptions;
protected readonly TokenCredential _credentials;
protected readonly ArmClient _armClient;

private Dictionary<string, ResourceGroupResource> _storageResourceGroups;

public AzureResourceProvider(TokenCredential credential, GlobalOptions options)
{
_globalOptions = options;
_credentials = credential;
var clientOptions = new ArmClientOptions();
clientOptions.Diagnostics.ApplicationId = $"AMSMigrate/{GetType().Assembly.GetName().Version}";
var armClient = new ArmClient(credential, default, clientOptions);
_armClient = new ArmClient(credential, default, clientOptions);
var resourceGroupId = ResourceGroupResource.CreateResourceIdentifier(
options.SubscriptionId,
options.ResourceGroup);
_resourceGroup = armClient.GetResourceGroupResource(resourceGroupId);
_resourceGroup = _armClient.GetResourceGroupResource(resourceGroupId);
_storageResourceGroups = new Dictionary<string, ResourceGroupResource>();
}

public async Task SetStorageResourceGroupsAsync(MediaServicesAccountResource account, CancellationToken cancellationToken)
{
IList<MediaServicesStorageAccount> storageAccounts;
var mediaServiceResource = await account.GetAsync(cancellationToken: cancellationToken);
if (mediaServiceResource.GetRawResponse().Status == 200)
{
storageAccounts = mediaServiceResource.Value.Data.StorageAccounts;
if (storageAccounts != null && storageAccounts.Any())
{
foreach (var storageAccount in storageAccounts)
{
string? storageAccountId = storageAccount.Id;
///subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/microsoft.storage/storageaccounts/{accountName}
if (!string.IsNullOrEmpty(storageAccountId))
{
string[] parts;
parts = storageAccountId.Split('/');
string resourceGroupName = parts[4];
string storageAccName = parts[8];
string subscriptionId = parts[2];
var resourceGroupId = ResourceGroupResource.CreateResourceIdentifier(
subscriptionId,
resourceGroupName);
var resourceGroup = _armClient.GetResourceGroupResource(resourceGroupId);
_storageResourceGroups.Add(storageAccName, resourceGroup);
}
}
}

}
}

public async Task<MediaServicesAccountResource> GetMediaAccountAsync(
string mediaAccountName,
CancellationToken cancellationToken)
{
return await _resourceGroup.GetMediaServicesAccountAsync(
mediaAccountName, cancellationToken);
}
mediaAccountName, cancellationToken);
}

public async Task<BlobServiceClient> GetStorageAccountAsync(
MediaServicesAccountResource account,
MediaAssetResource asset,
CancellationToken cancellationToken)
{
string assetStorageAccountName = asset.Data.StorageAccountName;
var resource = await _resourceGroup.GetStorageAccountAsync(asset.Data.StorageAccountName, cancellationToken: cancellationToken);
_storageResourceGroups.TryGetValue(asset.Data.StorageAccountName, out var rg);
var resource = await rg.GetStorageAccountAsync(asset.Data.StorageAccountName, cancellationToken: cancellationToken);
return GetStorageAccount(resource);
}

Expand Down
3 changes: 1 addition & 2 deletions ams/CleanupCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public override async Task MigrateAsync(CancellationToken cancellationToken)
var resourceFilter = _options.IsCleanUpAccount ? null : GetAssetResourceFilter(_options.ResourceFilter, null, null);

var orderBy = "properties/created";
await _resourceProvider.SetStorageResourceGroupsAsync(account, cancellationToken);
assets = account.GetMediaAssets()
.GetAllAsync(resourceFilter, orderby: orderBy, cancellationToken: cancellationToken);
List<MediaAssetResource>? assetList = await assets.ToListAsync(cancellationToken);
Expand Down Expand Up @@ -161,10 +162,8 @@ private async Task<bool> CleanUpAssetAsync(bool isForcedelete, MediaServicesAcco
if (!await container.ExistsAsync(cancellationToken))
{
_logger.LogWarning("Container {name} missing for asset {asset}", container.Name, asset.Data.Name);

return false;
}

// The asset container exists, try to check the metadata list first.

if (isForcedelete || (_tracker.GetMigrationStatusAsync(container, cancellationToken).Result.Status == MigrationStatus.Completed))
Expand Down
2 changes: 1 addition & 1 deletion ams/ResetCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public override async Task MigrateAsync(CancellationToken cancellationToken)
{
var account = await GetMediaAccountAsync(_options.AccountName, cancellationToken);
_logger.LogInformation("Begin reset assets on account: {name}", account.Data.Name);

await _resourceProvider.SetStorageResourceGroupsAsync(account, cancellationToken);
AsyncPageable<MediaAssetResource> assets = account.GetMediaAssets()
.GetAllAsync(cancellationToken: cancellationToken);
List<MediaAssetResource>? assetList = await assets.ToListAsync(cancellationToken);
Expand Down

0 comments on commit 1a70d8c

Please sign in to comment.