Skip to content

Commit e387779

Browse files
authored
Merge pull request Azure#10652 from Azure/storagesync-register-storageaccount-subscription
Az.StorageSync | Register Subscription when different than current context.
2 parents 42661bf + 12b1485 commit e387779

File tree

6 files changed

+146
-10
lines changed

6 files changed

+146
-10
lines changed

src/StorageSync/StorageSync/CloudEndpoint/NewCloudEndpointCommand.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
using Microsoft.Azure.Management.StorageSync;
2525
using Microsoft.Azure.Management.StorageSync.Models;
2626
using Microsoft.WindowsAzure.Commands.Utilities.Common;
27+
using System;
2728
using System.Management.Automation;
2829
using StorageSyncModels = Microsoft.Azure.Management.StorageSync.Models;
2930

@@ -192,6 +193,24 @@ public override void ExecuteCmdlet()
192193
throw new PSArgumentException(nameof(StorageAccountResourceId));
193194
}
194195

196+
if(this.IsParameterBound(c=>c.StorageAccountTenantId))
197+
{
198+
if(StorageAccountTenantId != AzureContext.Tenant.Id)
199+
{
200+
throw new PSArgumentException(string.Format(StorageSyncResources.NewCloudEndpointCrossTenantErrorFormat, StorageAccountTenantId, AzureContext.Tenant.Id));
201+
}
202+
}
203+
204+
if(storageAccountResourceIdentifier.Subscription != AzureContext.Subscription.Id)
205+
{
206+
WriteWarning(string.Format(StorageSyncResources.NewCloudEndpointCrossSubscriptionWarningFormat, storageAccountResourceIdentifier.Subscription , AzureContext.Subscription.Id));
207+
208+
if(!StorageSyncClientWrapper.TryRegisterProvider(AzureContext.Subscription.Id,StorageSyncConstants.ResourceProvider, storageAccountResourceIdentifier.Subscription))
209+
{
210+
WriteWarning(string.Format(StorageSyncResources.NewCloudEndpointUnableToRegisterErrorFormat, storageAccountResourceIdentifier.Subscription));
211+
}
212+
}
213+
195214
PSADServicePrincipal servicePrincipal = StorageSyncClientWrapper.EnsureServicePrincipal();
196215
RoleAssignment roleAssignment = StorageSyncClientWrapper.EnsureRoleAssignment(servicePrincipal, StorageAccountResourceId);
197216

@@ -211,7 +230,7 @@ public override void ExecuteCmdlet()
211230
{
212231
StorageAccountResourceId = StorageAccountResourceId,
213232
AzureFileShareName = AzureFileShareName,
214-
StorageAccountTenantId = (StorageAccountTenantId ?? DefaultContext.Tenant?.Id)
233+
StorageAccountTenantId = (StorageAccountTenantId ?? AzureContext.Tenant.Id)
215234
};
216235

217236
string resourceGroupName = ResourceGroupName ?? ParentObject?.ResourceGroupName ?? parentResourceIdentifier.ResourceGroupName;
@@ -233,5 +252,6 @@ public override void ExecuteCmdlet()
233252
}
234253
});
235254
}
255+
236256
}
237257
}

src/StorageSync/StorageSync/Common/StorageSyncClientCmdletBase.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313
// ----------------------------------------------------------------------------------
1414

1515
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
16+
using Microsoft.Azure.Commands.ResourceManager.Common.Properties;
1617
using Microsoft.Azure.Commands.StorageSync.Common.Converters;
1718
using Microsoft.Azure.Commands.StorageSync.Common.Exceptions;
1819
using Microsoft.Azure.Commands.StorageSync.Interfaces;
1920
using Microsoft.Azure.Graph.RBAC.Version1_6_20190326.ActiveDirectory;
2021
using System;
2122
using System.Collections.Generic;
2223
using System.Linq;
24+
using System.Management.Automation;
2325
using StorageSyncModels = Microsoft.Azure.Management.StorageSync.Models;
2426

2527
namespace Microsoft.Azure.Commands.StorageSync.Common
@@ -74,7 +76,27 @@ public StorageSyncClientCmdletBase()
7476
/// </summary>
7577
protected virtual void InitializeComponent()
7678
{
77-
DefaultProfile.DefaultContext.Tenant.Id = StorageSyncClientWrapper.StorageSyncResourceManager.GetTenantId() ?? DefaultProfile.DefaultContext.Tenant.Id;
79+
AzureContext.Tenant.Id = StorageSyncClientWrapper.StorageSyncResourceManager.GetTenantId() ?? AzureContext.Tenant.Id;
80+
}
81+
82+
/// <summary>
83+
/// Gets the current default context.
84+
/// </summary>
85+
protected virtual IAzureContext AzureContext
86+
{
87+
get
88+
{
89+
if (DefaultProfile == null || DefaultProfile.DefaultContext == null || DefaultProfile.DefaultContext.Account == null)
90+
{
91+
throw new PSInvalidOperationException(Resources.RunConnectAccount);
92+
}
93+
if (DefaultProfile.DefaultContext.Subscription == null)
94+
{
95+
throw new PSInvalidOperationException(string.Format(Resources.NoSubscriptionFound, DefaultProfile.DefaultContext.Tenant.Id));
96+
}
97+
98+
return DefaultProfile.DefaultContext;
99+
}
78100
}
79101

80102
/// <summary>
@@ -93,7 +115,7 @@ protected virtual void InitializeComponent()
93115
/// Gets the subscription identifier.
94116
/// </summary>
95117
/// <value>The subscription identifier.</value>
96-
public Guid SubscriptionId => DefaultProfile.DefaultContext.Subscription.GetId();
118+
public Guid SubscriptionId => AzureContext.Subscription.GetId();
97119

98120
/// <summary>
99121
/// Gets or sets the storage sync client wrapper.
@@ -105,7 +127,7 @@ public IStorageSyncClientWrapper StorageSyncClientWrapper
105127
{
106128
if (storageSyncClientWrapper == null)
107129
{
108-
storageSyncClientWrapper = new StorageSyncClientWrapper(DefaultProfile.DefaultContext, ActiveDirectoryClient);
130+
storageSyncClientWrapper = new StorageSyncClientWrapper(AzureContext, ActiveDirectoryClient);
109131
}
110132

111133
storageSyncClientWrapper.VerboseLogger = WriteVerboseWithTimestamp;

src/StorageSync/StorageSync/Common/StorageSyncClientWrapper.cs

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using Microsoft.Azure.Graph.RBAC.Version1_6_20190326.Models;
2121
using Microsoft.Azure.Management.Authorization.Version2015_07_01;
2222
using Microsoft.Azure.Management.Authorization.Version2015_07_01.Models;
23+
using Microsoft.Azure.Management.Internal.Resources;
2324
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
2425
using Microsoft.Azure.Management.StorageSync;
2526
using Microsoft.Rest.Azure.OData;
@@ -29,6 +30,7 @@
2930
using System.Collections.Generic;
3031
using System.Linq;
3132
using System.Management.Automation;
33+
using System.Net.Http;
3234

3335
namespace Microsoft.Azure.Commands.StorageSync.Common
3436
{
@@ -81,6 +83,12 @@ public class StorageSyncClientWrapper : IStorageSyncClientWrapper
8183
/// <value>The authorization management client.</value>
8284
public IAuthorizationManagementClient AuthorizationManagementClient { get; set; }
8385

86+
/// <summary>
87+
/// Gets or sets the resource management client.
88+
/// </summary>
89+
/// <value>The resource management client.</value>
90+
public IResourceManagementClient ResourceManagementClient { get; set; }
91+
8492
/// <summary>
8593
/// Gets or sets the active directory client.
8694
/// </summary>
@@ -105,9 +113,9 @@ public class StorageSyncClientWrapper : IStorageSyncClientWrapper
105113
/// <param name="context">The context.</param>
106114
/// <param name="activeDirectoryClient">The active directory client.</param>
107115
public StorageSyncClientWrapper(IAzureContext context, ActiveDirectoryClient activeDirectoryClient)
108-
: this(
109-
AzureSession.Instance.ClientFactory.CreateArmClient<StorageSyncManagementClient>(context, AzureEnvironment.Endpoint.ResourceManager),
110-
AzureSession.Instance.ClientFactory.CreateArmClient<AuthorizationManagementClient>(context, AzureEnvironment.Endpoint.ResourceManager))
116+
: this(AzureSession.Instance.ClientFactory.CreateArmClient<StorageSyncManagementClient>(context, AzureEnvironment.Endpoint.ResourceManager),
117+
AzureSession.Instance.ClientFactory.CreateArmClient<AuthorizationManagementClient>(context, AzureEnvironment.Endpoint.ResourceManager),
118+
AzureSession.Instance.ClientFactory.CreateArmClient<ResourceManagementClient>(context, AzureEnvironment.Endpoint.ResourceManager))
111119
{
112120
ActiveDirectoryClient = activeDirectoryClient;
113121

@@ -126,10 +134,15 @@ public StorageSyncClientWrapper(IAzureContext context, ActiveDirectoryClient act
126134
/// </summary>
127135
/// <param name="storageSyncManagementClient">The storage sync management client.</param>
128136
/// <param name="authorizationManagementClient">The authorization management client.</param>
129-
public StorageSyncClientWrapper(IStorageSyncManagementClient storageSyncManagementClient, AuthorizationManagementClient authorizationManagementClient)
137+
/// <param name="resourceManagementClient">The resource management client.</param>
138+
public StorageSyncClientWrapper(
139+
IStorageSyncManagementClient storageSyncManagementClient,
140+
AuthorizationManagementClient authorizationManagementClient,
141+
ResourceManagementClient resourceManagementClient)
130142
{
131143
StorageSyncManagementClient = storageSyncManagementClient;
132144
AuthorizationManagementClient = authorizationManagementClient;
145+
ResourceManagementClient = resourceManagementClient;
133146
}
134147

135148
/// <summary>
@@ -298,5 +311,30 @@ public RoleAssignment EnsureRoleAssignment(PSADServicePrincipal serverPrincipal,
298311

299312
return roleAssignment;
300313
}
314+
315+
/// <summary>
316+
/// This function will invoke the registration and continue operation with a success function call.
317+
/// </summary>
318+
/// <param name="currentSubscriptionId">Current SubscriptionId in Azure Context</param>
319+
/// <param name="resourceProviderNamespace">Resource provider name</param>
320+
/// <param name="subscription">subscription</param>
321+
/// <returns>true if request was successfully made. else false</returns>
322+
public bool TryRegisterProvider(string currentSubscriptionId, string resourceProviderNamespace, string subscription)
323+
{
324+
try
325+
{
326+
ResourceManagementClient.SubscriptionId = subscription;
327+
ResourceManagementClient.Providers.RegisterAsync(resourceProviderNamespace);
328+
return true;
329+
}
330+
catch (HttpRequestException)
331+
{
332+
return false;
333+
}
334+
finally
335+
{
336+
ResourceManagementClient.SubscriptionId = currentSubscriptionId;
337+
}
338+
}
301339
}
302340
}

src/StorageSync/StorageSync/Interfaces/IStorageSyncClientWrapper.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,23 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15+
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
1516
using Microsoft.Azure.Graph.RBAC.Version1_6_20190326.ActiveDirectory;
1617
using Microsoft.Azure.Management.Authorization.Version2015_07_01;
1718
using Microsoft.Azure.Management.Authorization.Version2015_07_01.Models;
19+
using Microsoft.Azure.Management.Internal.Resources;
1820
using Microsoft.Azure.Management.StorageSync;
1921
using System;
2022

2123
namespace Microsoft.Azure.Commands.StorageSync.Interfaces
2224
{
25+
2326
/// <summary>
2427
/// Interface IStorageSyncClientWrapper
2528
/// </summary>
2629
public interface IStorageSyncClientWrapper
2730
{
31+
2832
/// <summary>
2933
/// Gets or sets the active directory client.
3034
/// </summary>
@@ -48,6 +52,13 @@ public interface IStorageSyncClientWrapper
4852
/// </summary>
4953
/// <value>The authorization management client.</value>
5054
IAuthorizationManagementClient AuthorizationManagementClient { get; set; }
55+
56+
/// <summary>
57+
/// Gets or sets the resource management client.
58+
/// </summary>
59+
/// <value>The resource management client.</value>
60+
IResourceManagementClient ResourceManagementClient { get; set; }
61+
5162
/// <summary>
5263
/// Gets or sets the verbose logger.
5364
/// </summary>
@@ -74,6 +85,15 @@ public interface IStorageSyncClientWrapper
7485
/// <returns>RoleAssignment.</returns>
7586
RoleAssignment EnsureRoleAssignment(PSADServicePrincipal serverPrincipal,string resourceId);
7687

88+
/// <summary>
89+
/// This function will invoke the registration and continue operation with a success function call.
90+
/// </summary>
91+
/// <param name="currentSubscriptionId">Current SubscriptionId in Azure Context</param>
92+
/// <param name="resourceProviderNamespace">Resource provider name</param>
93+
/// <param name="subscription">subscription</param>
94+
/// <returns>true if request was successfully made. else false</returns>
95+
bool TryRegisterProvider(string currentSubscriptionId, string resourceProviderNamespace, string subscription);
96+
7797
/// <summary>
7898
/// Gets the afs agent installer path.
7999
/// </summary>

src/StorageSync/StorageSync/Properties/StorageSyncResources.Designer.cs

Lines changed: 29 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/StorageSync/StorageSync/Properties/StorageSyncResources.resx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,4 +270,13 @@
270270
<data name="InvokeChangeDetectionActionMessage" xml:space="preserve">
271271
<value>Invoke change detection for Cloud Endpoint</value>
272272
</data>
273+
<data name="NewCloudEndpointCrossSubscriptionWarningFormat" xml:space="preserve">
274+
<value>The given storage account subscription {0} is in other subscription than the current azure context subscription {1}. We will try to inform Azure File Sync about the storage account subscription.</value>
275+
</data>
276+
<data name="NewCloudEndpointCrossTenantErrorFormat" xml:space="preserve">
277+
<value>The given storage account tenant {0} does not match with current azure tenant. We do not support cloud endpoint creation with storage account pointing to any other tenant than itself. Please try this operation again with correct tenant.</value>
278+
</data>
279+
<data name="NewCloudEndpointUnableToRegisterErrorFormat" xml:space="preserve">
280+
<value>The given subscription {0} was unable to registered to Azure File Sync.</value>
281+
</data>
273282
</root>

0 commit comments

Comments
 (0)