Skip to content

Commit 39db20f

Browse files
Az.StorageSync : Hot fixes for Aug Release (#25625)
* Az.StorageSync : Hot fixes for Aug Release * Optimize 120 seconds wait for MI propogation in msft entra * Add Identity to PSStorageSyncService * Do not fail fast but iterate through all and return first exception * Update SetStorageSyncServiceIdentityCommand.cs * Update ChangeLog.md * Update ChangeLog.md --------- Co-authored-by: Yabo Hu <[email protected]>
1 parent e04e422 commit 39db20f

File tree

5 files changed

+89
-52
lines changed

5 files changed

+89
-52
lines changed

src/StorageSync/StorageSync/ChangeLog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
- Additional information about change #1
1919
-->
2020
## Upcoming Release
21-
21+
* Fixed the Register-AzStorageSyncServer with Azure FileSync Agent v17
22+
* Improved performance for Managed Identity migration cmdlet
2223
## Version 2.2.0
2324
* Onboarded Service Api version 2022-09-01
2425
* Enabled ManagedIdentity Feature (Preview)

src/StorageSync/StorageSync/Common/Converters/StorageSyncServiceConverter.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public StorageSyncServiceConverter()
4949
StorageSyncConstants.StorageSyncServiceType,
5050
new SystemDataConverter().Convert(source.SystemData),
5151
source.Tags,
52-
null,
52+
source.Identity,
5353
source.IncomingTrafficPolicy);
5454

5555
/// <summary>
@@ -82,7 +82,8 @@ protected override PSStorageSyncService Transform(StorageSyncModels.StorageSyncS
8282
Type = resourceIdentifier.ResourceType ?? StorageSyncConstants.StorageSyncServiceType,
8383
PrivateEndpointConnections = psPrivateEndpointConnections.Count > 0 ? psPrivateEndpointConnections : null,
8484
SystemData = new SystemDataConverter().Convert(source.SystemData),
85-
UseIdentity = source.UseIdentity
85+
UseIdentity = source.UseIdentity,
86+
Identity = source.Identity
8687
};
8788
}
8889
}

src/StorageSync/StorageSync/Models/PSStorageSyncService.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,10 @@ public class PSStorageSyncService : PSResourceBase
7878
/// <value>The SystemData.</value>
7979
public PSSystemData SystemData { get; set; }
8080

81+
/// <summary>
82+
/// Managed Identity for Storage Sync Service
83+
/// </summary>
84+
public ManagedServiceIdentity Identity { get; set; }
85+
8186
}
8287
}

src/StorageSync/StorageSync/RegisteredServer/RegisterServerCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ private RegisteredServer CreateRegisteredResourceInCloud(string resourceGroupNam
228228
ClusterName = serverRegistrationData.ClusterName,
229229
AgentVersion = serverRegistrationData.AgentVersion,
230230
//ApplicationId = serverRegistrationData.ApplicationId.HasValue ? serverRegistrationData.ApplicationId.Value.ToString() : null,
231-
ApplicationId = null,
231+
ApplicationId = Guid.Empty.ToString(),
232232
ServerCertificate = serverRegistrationData.ServerCertificate != null ? Convert.ToBase64String(serverRegistrationData.ServerCertificate) : null,
233233
ServerOSVersion = serverRegistrationData.ServerOSVersion,
234234
ServerRole = serverRegistrationData.ServerRole.ToString(),

src/StorageSync/StorageSync/StorageSyncService/SetStorageSyncServiceIdentityCommand.cs

Lines changed: 78 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ public override void ExecuteCmdlet()
152152
if (ShouldProcess(Target, ActionMessage))
153153
{
154154
StorageSyncModels.StorageSyncService storageSyncService = StorageSyncClientWrapper.StorageSyncManagementClient.StorageSyncServices.Get(resourceGroupName, resourceName);
155+
bool needPropogationDelay = storageSyncService?.Identity?.Type != ManagedServiceIdentityType.SystemAssigned.ToString();
156+
155157
// 1. Check if any server available for migration
156158
IEnumerable<StorageSyncModels.RegisteredServer> registeredServers = StorageSyncClientWrapper.StorageSyncManagementClient.RegisteredServers.ListByStorageSyncService(resourceGroupName, resourceName);
157159
var candidateServersLookup = new Dictionary<string, StorageSyncModels.RegisteredServer>(StringComparer.InvariantCultureIgnoreCase);
@@ -211,71 +213,99 @@ public override void ExecuteCmdlet()
211213
StorageSyncClientWrapper.VerboseLogger.Invoke($"Storage Sync Service is capable with identity {storageSyncService.Identity.PrincipalId}");
212214
}
213215

214-
StorageSyncClientWrapper.VerboseLogger.Invoke($"If you are creating this principal and then immediately assigning a role, you will get error PrincipalNotFound which is related to a replication delay. In this case, set the role assignment principalType property to a value, such as ServicePrincipal, User, or Group. See\r\nhttps://aka.ms/docs-principaltype");
215-
StorageSyncClientWrapper.VerboseLogger.Invoke($"Sleeping for 120 seconds...");
216-
Thread.Sleep(TimeSpan.FromSeconds(120));
216+
if (needPropogationDelay)
217+
{
218+
StorageSyncClientWrapper.VerboseLogger.Invoke($"If you are creating this principal and then immediately assigning a role, you will get error PrincipalNotFound which is related to a replication delay. In this case, set the role assignment principalType property to a value, such as ServicePrincipal, User, or Group. See\r\nhttps://aka.ms/docs-principaltype");
219+
StorageSyncClientWrapper.VerboseLogger.Invoke($"Sleeping for 120 seconds...");
220+
Thread.Sleep(TimeSpan.FromSeconds(120));
221+
}
217222

218223
// 3. RBAC permission set for Cloud Endpoints and Server Endpoints
219224
IEnumerable<StorageSyncModels.SyncGroup> syncGroups = StorageSyncClientWrapper.StorageSyncManagementClient.SyncGroups.ListByStorageSyncService(resourceGroupName, resourceName);
225+
Exception syncGroupFirstException = null;
220226
foreach (var syncGroup in syncGroups)
221227
{
222-
IEnumerable<StorageSyncModels.CloudEndpoint> cloudEndpoints = StorageSyncClientWrapper.StorageSyncManagementClient.CloudEndpoints.ListBySyncGroup(resourceGroupName, resourceName, syncGroup.Name);
223-
StorageSyncModels.CloudEndpoint cloudEndpoint = cloudEndpoints.FirstOrDefault();
224-
225-
if (cloudEndpoint == null)
228+
try
226229
{
227-
StorageSyncClientWrapper.VerboseLogger.Invoke($"Skipping SyncGroup. No cloud Endpoint found for sync group {syncGroup.Name}");
228-
continue;
229-
}
230-
var storageAccountResourceIdentifier = new ResourceIdentifier(cloudEndpoint.StorageAccountResourceId);
230+
IEnumerable<StorageSyncModels.CloudEndpoint> cloudEndpoints = StorageSyncClientWrapper.StorageSyncManagementClient.CloudEndpoints.ListBySyncGroup(resourceGroupName, resourceName, syncGroup.Name);
231+
StorageSyncModels.CloudEndpoint cloudEndpoint = cloudEndpoints.FirstOrDefault();
231232

232-
// Identity , RoleDef, Scope
233-
var scope = cloudEndpoint.StorageAccountResourceId;
234-
var identityRoleAssignmentForSAScope = StorageSyncClientWrapper.EnsureRoleAssignmentWithIdentity(storageAccountResourceIdentifier.Subscription,
235-
storageSyncService.Identity.PrincipalId.Value,
236-
Common.StorageSyncClientWrapper.StorageAccountContributorRoleDefinitionId,
237-
scope);
233+
if (cloudEndpoint == null)
234+
{
235+
StorageSyncClientWrapper.VerboseLogger.Invoke($"Skipping SyncGroup. No cloud Endpoint found for sync group {syncGroup.Name}");
236+
continue;
237+
}
238+
var storageAccountResourceIdentifier = new ResourceIdentifier(cloudEndpoint.StorageAccountResourceId);
238239

239-
scope = $"{cloudEndpoint.StorageAccountResourceId}/fileServices/default/fileshares/{cloudEndpoint.AzureFileShareName}";
240-
var identityRoleAssignmentForFilsShareScope = StorageSyncClientWrapper.EnsureRoleAssignmentWithIdentity(storageAccountResourceIdentifier.Subscription,
241-
storageSyncService.Identity.PrincipalId.Value,
242-
Common.StorageSyncClientWrapper.StorageFileDataPrivilegedContributorRoleDefinitionId,
243-
scope);
240+
// Identity , RoleDef, Scope
241+
var scope = cloudEndpoint.StorageAccountResourceId;
242+
var identityRoleAssignmentForSAScope = StorageSyncClientWrapper.EnsureRoleAssignmentWithIdentity(storageAccountResourceIdentifier.Subscription,
243+
storageSyncService.Identity.PrincipalId.Value,
244+
Common.StorageSyncClientWrapper.StorageAccountContributorRoleDefinitionId,
245+
scope);
244246

245-
IEnumerable<StorageSyncModels.ServerEndpoint> serverEndpoints = StorageSyncClientWrapper.StorageSyncManagementClient.ServerEndpoints.ListBySyncGroup(resourceGroupName, resourceName, syncGroup.Name);
246-
foreach (var serverEndpoint in serverEndpoints)
247-
{
248-
var associatedServers = new List<RegisteredServer>();
247+
scope = $"{cloudEndpoint.StorageAccountResourceId}/fileServices/default/fileshares/{cloudEndpoint.AzureFileShareName}";
248+
var identityRoleAssignmentForFilsShareScope = StorageSyncClientWrapper.EnsureRoleAssignmentWithIdentity(storageAccountResourceIdentifier.Subscription,
249+
storageSyncService.Identity.PrincipalId.Value,
250+
Common.StorageSyncClientWrapper.StorageFileDataPrivilegedContributorRoleDefinitionId,
251+
scope);
249252

250-
// It is expected that multiple migration script might have caused to have role assignment already in the system. We are fault tolerant to existing role assignment.
251-
if (candidateServersLookup.ContainsKey(serverEndpoint.ServerResourceId))
252-
{
253-
// Standalone Server scenario
254-
associatedServers.Add(candidateServersLookup[serverEndpoint.ServerResourceId]);
255-
}
256-
else if (clusterNameServersLookup.ContainsKey(serverEndpoint.ServerResourceId))
253+
IEnumerable<StorageSyncModels.ServerEndpoint> serverEndpoints = StorageSyncClientWrapper.StorageSyncManagementClient.ServerEndpoints.ListBySyncGroup(resourceGroupName, resourceName, syncGroup.Name);
254+
Exception serverEndpointFirstException = null;
255+
foreach (var serverEndpoint in serverEndpoints)
257256
{
258-
// ClusterNode Server scenario
259-
associatedServers.AddRange(clusterNameServersLookup[serverEndpoint.ServerResourceId]);
260-
}
257+
try
258+
{
259+
var associatedServers = new List<RegisteredServer>();
261260

262-
StorageSyncClientWrapper.VerboseLogger.Invoke($"ServerEndpoint {serverEndpoint.Name} has {associatedServers.Count} associated registered servers.");
263-
foreach (var associatedServer in associatedServers)
264-
{
265-
if (!Guid.TryParse(associatedServer.LatestApplicationId, out Guid applicationGuid))
261+
// It is expected that multiple migration script might have caused to have role assignment already in the system. We are fault tolerant to existing role assignment.
262+
if (candidateServersLookup.ContainsKey(serverEndpoint.ServerResourceId))
263+
{
264+
// Standalone Server scenario
265+
associatedServers.Add(candidateServersLookup[serverEndpoint.ServerResourceId]);
266+
}
267+
else if (clusterNameServersLookup.ContainsKey(serverEndpoint.ServerResourceId))
268+
{
269+
// ClusterNode Server scenario
270+
associatedServers.AddRange(clusterNameServersLookup[serverEndpoint.ServerResourceId]);
271+
}
272+
273+
StorageSyncClientWrapper.VerboseLogger.Invoke($"ServerEndpoint {serverEndpoint.Name} has {associatedServers.Count} associated registered servers.");
274+
foreach (var associatedServer in associatedServers)
275+
{
276+
if (!Guid.TryParse(associatedServer.LatestApplicationId, out Guid applicationGuid))
277+
{
278+
applicationGuid = Guid.Parse(associatedServer.ApplicationId);
279+
}
280+
// Identity , RoleDef, Scope
281+
scope = $"{cloudEndpoint.StorageAccountResourceId}/fileServices/default/fileshares/{cloudEndpoint.AzureFileShareName}";
282+
identityRoleAssignmentForFilsShareScope = StorageSyncClientWrapper.EnsureRoleAssignmentWithIdentity(storageAccountResourceIdentifier.Subscription,
283+
applicationGuid,
284+
Common.StorageSyncClientWrapper.StorageFileDataPrivilegedContributorRoleDefinitionId,
285+
scope);
286+
}
287+
}
288+
catch (Exception ex)
266289
{
267-
applicationGuid = Guid.Parse(associatedServer.ApplicationId);
290+
StorageSyncClientWrapper.ErrorLogger.Invoke($"ServerEndpoint {serverEndpoint.Name} has failed with an exception {ex.Message}.");
291+
serverEndpointFirstException = serverEndpointFirstException ?? ex;
268292
}
269-
// Identity , RoleDef, Scope
270-
scope = $"{cloudEndpoint.StorageAccountResourceId}/fileServices/default/fileshares/{cloudEndpoint.AzureFileShareName}";
271-
identityRoleAssignmentForFilsShareScope = StorageSyncClientWrapper.EnsureRoleAssignmentWithIdentity(storageAccountResourceIdentifier.Subscription,
272-
applicationGuid,
273-
Common.StorageSyncClientWrapper.StorageFileDataPrivilegedContributorRoleDefinitionId,
274-
scope);
293+
} // Iterating server endpoints
294+
if (serverEndpointFirstException != null)
295+
{
296+
throw serverEndpointFirstException;
275297
}
276298
}
299+
catch (Exception ex)
300+
{
301+
StorageSyncClientWrapper.ErrorLogger.Invoke($"SyncGroup {syncGroup.Name} has failed with an exception {ex.Message}.");
302+
syncGroupFirstException = syncGroupFirstException ?? ex;
303+
}
304+
} // Iterating sync groups
305+
if (syncGroupFirstException != null)
306+
{
307+
throw syncGroupFirstException;
277308
}
278-
279309
// 4 Set UseIdentity for given Storage Sync Service
280310
updateParameters = new StorageSyncServiceUpdateParameters()
281311
{

0 commit comments

Comments
 (0)