diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/ProxyResource.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/ProxyResource.cs index ac7ce5335c1b..5b0925c4b983 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/ProxyResource.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/ProxyResource.cs @@ -7,22 +7,24 @@ namespace Azure.ResourceManager.Core /// A class representing a generic proxy resource in Azure /// /// The type of the underlying model this class wraps - public abstract class ProxyResource : Resource - where TModel : class + /// The type of the underlying modelresource Id + public abstract class ProxyResource : Resource + where TModel : class + where TIdentifier : TenantResourceIdentifier { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The identifier of the resource that is the target of operations. /// The model to copy from. - protected ProxyResource(ResourceIdentifier id, TModel data) + protected ProxyResource(TIdentifier id, TModel data) { Id = id; Model = data; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The identifier of the resource that is the target of operations. /// The model to copy from. @@ -34,7 +36,7 @@ protected ProxyResource(string id, TModel data) } else { - Id = id; + Id = ResourceIdentifier.Create(id) as TIdentifier; } Model = data; @@ -43,7 +45,7 @@ protected ProxyResource(string id, TModel data) /// /// Gets or sets the identifier for the resource. /// - public override ResourceIdentifier Id { get; protected set; } + public override TIdentifier Id { get; protected set; } /// /// Gets or sets the Model this resource is based off. @@ -51,10 +53,10 @@ protected ProxyResource(string id, TModel data) public virtual TModel Model { get; set; } /// - /// Converts from a into the TModel. + /// Converts from a into the TModel. /// /// The tracked resource convert from. - public static implicit operator TModel(ProxyResource other) + public static implicit operator TModel(ProxyResource other) { return other.Model; } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/TrackedResource.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/TrackedResource.cs index f6aed917167f..4a3ae7ccf0b2 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/TrackedResource.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Adapters/TrackedResource.cs @@ -8,17 +8,19 @@ namespace Azure.ResourceManager.Core /// /// A class representing a generic tracked resource in Azure. /// + /// The type of the underlying resource id /// The type of the underlying model this class wraps - public abstract class TrackedResource : TrackedResource + public abstract class TrackedResource : TrackedResource + where TIdentifier : TenantResourceIdentifier where TModel : class { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The identifier of the resource that is the target of operations. /// The location of the resource. /// The model to copy from. - protected TrackedResource(ResourceIdentifier id, LocationData location, TModel data) + protected TrackedResource(TIdentifier id, LocationData location, TModel data) { Id = id; Location = location; @@ -26,7 +28,7 @@ protected TrackedResource(ResourceIdentifier id, LocationData location, TModel d } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The identifier of the resource that is the target of operations. /// The location of the resource. @@ -39,7 +41,7 @@ protected TrackedResource(string id, LocationData location, TModel data) } else { - Id = id; + Id = ResourceIdentifier.Create(id) as TIdentifier; } Location = location; @@ -55,7 +57,7 @@ protected TrackedResource(string id, LocationData location, TModel data) /// Converts from a into the TModel. /// /// The tracked resource convert from. - public static implicit operator TModel(TrackedResource other) + public static implicit operator TModel(TrackedResource other) { return other.Model; } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ArmBuilder.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ArmBuilder.cs index 6660dbe67684..f58fd70e715f 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ArmBuilder.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ArmBuilder.cs @@ -10,18 +10,20 @@ namespace Azure.ResourceManager.Core /// /// A class representing a builder object used to create Azure resources. /// + /// The type of the Identifier class for a specific resource. /// The type of the operations class for a specific resource. /// The type of the class containing properties for the underlying resource. - public class ArmBuilder - where TResource : Resource - where TOperations : ResourceOperationsBase + public class ArmBuilder + where TIdentifier: TenantResourceIdentifier + where TResource : Resource + where TOperations : ResourceOperationsBase { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The container object to create the resource in. /// The resource to create. - public ArmBuilder(ResourceContainerBase container, TResource resource) + public ArmBuilder(ResourceContainerBase container, TResource resource) { Resource = resource; UnTypedContainer = container; @@ -40,7 +42,7 @@ public ArmBuilder(ResourceContainerBase container, TReso /// /// Gets the container object to create the resource in. /// - protected ResourceContainerBase UnTypedContainer { get; private set; } + protected ResourceContainerBase UnTypedContainer { get; private set; } /// /// Creates the resource object to send to the Azure API. diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/AzureResourceManagerClient.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/AzureResourceManagerClient.cs index 845397384fc9..ac17d0a2cebc 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/AzureResourceManagerClient.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/AzureResourceManagerClient.cs @@ -101,7 +101,7 @@ private AzureResourceManagerClient( DefaultSubscription = string.IsNullOrWhiteSpace(defaultSubscriptionId) ? GetDefaultSubscription() : GetSubscriptionOperations(defaultSubscriptionId).Get().Value; - _clientOptions.ApiVersions.SetProviderClient(credential, baseUri, DefaultSubscription.Id.Subscription); + _clientOptions.ApiVersions.SetProviderClient(credential, baseUri, DefaultSubscription.Id.SubscriptionId); } /// @@ -145,9 +145,9 @@ public virtual ResourceGroupOperations GetResourceGroupOperations(string subscri /// /// The resource identifier of the resource group. /// Resource group operations. - public virtual ResourceGroupOperations GetResourceGroupOperations(ResourceIdentifier resourceGroupId) + public virtual ResourceGroupOperations GetResourceGroupOperations(ResourceGroupResourceIdentifier resourceGroupId) { - return GetSubscriptionOperations(resourceGroupId.Subscription).GetResourceGroupOperations(resourceGroupId.ResourceGroup); + return GetSubscriptionOperations(resourceGroupId.SubscriptionId).GetResourceGroupOperations(resourceGroupId.ResourceGroupName); } /// diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ContainerBase.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ContainerBase.cs index 7195b18f3fda..229478888eb3 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ContainerBase.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ContainerBase.cs @@ -13,30 +13,31 @@ namespace Azure.ResourceManager.Core /// Base class representing collection of resources. /// /// The type of the class containing operations for the underlying resource. - public abstract class ContainerBase : OperationsBase - where TOperations : ResourceOperationsBase + /// The type of the resource identifier. + public abstract class ContainerBase : OperationsBase + where TOperations : ResourceOperationsBase where TIdentifier : ResourceIdentifier { /// - /// Initializes a new instance of the class for mocking. + /// Initializes a new instance of the class for mocking. /// protected ContainerBase() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The client parameters to use in these operations. /// The identifier of the resource that is the target of operations. /// A credential used to authenticate to an Azure Service. /// The base URI of the service. - protected ContainerBase(AzureResourceManagerClientOptions options, ResourceIdentifier id, TokenCredential credential, Uri baseUri) + protected ContainerBase(AzureResourceManagerClientOptions options, TIdentifier id, TokenCredential credential, Uri baseUri) : base(options, id, credential, baseUri) { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The resource representing the parent resource. protected ContainerBase(ResourceOperationsBase parent) @@ -104,15 +105,15 @@ public virtual bool DoesExist(string resourceName) /// Get an instance of the operations this container holds. /// /// The name of the resource to scope the operations to. - /// An instance of . - protected virtual ResourceOperationsBase GetOperation(string resourceName) + /// An instance of . + protected virtual ResourceOperationsBase GetOperation(string resourceName) { return Activator.CreateInstance( typeof(TOperations).BaseType, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, new object[] { Parent, resourceName }, - CultureInfo.InvariantCulture) as ResourceOperationsBase; + CultureInfo.InvariantCulture) as ResourceOperationsBase; } } } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceData.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceData.cs index 84f62ecfee69..aa1a3d892df3 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceData.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceData.cs @@ -9,7 +9,7 @@ namespace Azure.ResourceManager.Core /// /// A class representing the generic azure resource data model. /// - public class GenericResourceData : TrackedResource + public class GenericResourceData : TrackedResource { /// /// Initializes a new instance of the class. @@ -41,7 +41,7 @@ public GenericResourceData(ResourceManager.Resources.Models.GenericResource gene /// Initializes a new instance of the class. /// /// The identifier of the resource that is the target of operations. - public GenericResourceData(ResourceIdentifier id) + public GenericResourceData(TenantResourceIdentifier id) : base(id, LocationData.Default, null) { } @@ -51,13 +51,13 @@ public GenericResourceData(ResourceIdentifier id) /// /// The identifier of the resource that is the target of operations. /// The location of the resource. - public GenericResourceData(ResourceIdentifier id, LocationData location) + public GenericResourceData(TenantResourceIdentifier id, LocationData location) : base(id, location, null) { } /// - public override ResourceIdentifier Id { get; protected set; } + public override TenantResourceIdentifier Id { get; protected set; } /// /// Gets or sets who this resource is managed by. diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceOperations.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceOperations.cs index f99ef82f538e..185201af7588 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceOperations.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/GenericResourceOperations.cs @@ -13,14 +13,14 @@ namespace Azure.ResourceManager.Core /// /// A class representing the operations that can be performed over a specific ArmResource. /// - public class GenericResourceOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource + public class GenericResourceOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource { /// /// Initializes a new instance of the class. /// /// The resource operations to copy the options from. /// The identifier of the resource that is the target of operations. - internal GenericResourceOperations(ResourceOperationsBase operations, ResourceIdentifier id) + internal GenericResourceOperations(ResourceOperationsBase operations, TenantResourceIdentifier id) : base(operations, id) { } @@ -28,11 +28,23 @@ internal GenericResourceOperations(ResourceOperationsBase operations, ResourceId /// protected override ResourceType ValidResourceType => ResourceGroupOperations.ResourceType; - private ResourcesOperations Operations => new ResourcesManagementClient( - BaseUri, - Id.Subscription, - Credential, - ClientOptions.Convert()).Resources; + private ResourcesOperations Operations + { + get + { + string subscription; + if (!Id.TryGetSubscriptionId(out subscription)) + { + subscription = Guid.Empty.ToString(); + } + + return new ResourcesManagementClient( + BaseUri, + subscription, + Credential, + ClientOptions.Convert()).Resources; + } + } /// /// Delete the resource. @@ -242,7 +254,7 @@ await op.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), private string GetApiVersion(CancellationToken cancellationToken) { - string version = ClientOptions.ApiVersions.TryGetApiVersion(Id.Type, cancellationToken); + string version = ClientOptions.ApiVersions.TryGetApiVersion(Id.ResourceType, cancellationToken); if (version is null) { throw new InvalidOperationException($"An invalid resouce id was given {Id}"); @@ -251,7 +263,7 @@ private string GetApiVersion(CancellationToken cancellationToken) } private async Task GetApiVersionAsync(CancellationToken cancellationToken) { - string version = await ClientOptions.ApiVersions.TryGetApiVersionAsync(Id.Type, cancellationToken).ConfigureAwait(false); + string version = await ClientOptions.ApiVersions.TryGetApiVersionAsync(Id.ResourceType, cancellationToken).ConfigureAwait(false); if (version is null) { throw new InvalidOperationException($"An invalid resouce id was given {Id}"); diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ITaggableResource.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ITaggableResource.cs index 812d8f072704..c33b18ada7af 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ITaggableResource.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ITaggableResource.cs @@ -10,9 +10,11 @@ namespace Azure.ResourceManager.Core /// /// Interface for operations that allow manipulating resource tags. /// + /// The identifier type for this resource. /// The typed operations for a specific resource. - public interface ITaggableResource - where TOperations : ResourceOperationsBase + public interface ITaggableResource + where TOperations : ResourceOperationsBase + where TIdentifier : TenantResourceIdentifier { /// /// Add a tag to the resource. diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/OperationsBase.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/OperationsBase.cs index 51dadf390af0..b8342b36b658 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/OperationsBase.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/OperationsBase.cs @@ -68,11 +68,19 @@ protected OperationsBase(AzureResourceManagerClientOptions options, ResourceIden /// /// Gets the resource client. /// - protected ResourcesManagementClient ResourcesClient => new ResourcesManagementClient( - BaseUri, - Id.Subscription, - Credential, - ClientOptions.Convert()); + protected ResourcesManagementClient ResourcesClient + { + get + { + string subscription; + if (!Id.TryGetSubscriptionId(out subscription)) + { + subscription = Guid.Empty.ToString(); + } + + return new ResourcesManagementClient(BaseUri, subscription, Credential, ClientOptions.Convert()); + } + } /// /// Validate the resource identifier against current operations. @@ -80,8 +88,8 @@ protected OperationsBase(AzureResourceManagerClientOptions options, ResourceIden /// The resource identifier. protected virtual void Validate(ResourceIdentifier identifier) { - if (identifier?.Type != ValidResourceType) - throw new ArgumentException($"Invalid resource type {identifier?.Type} expected {ValidResourceType}"); + if (identifier?.ResourceType != ValidResourceType) + throw new ArgumentException($"Invalid resource type {identifier?.ResourceType} expected {ValidResourceType}"); } } } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/ResourceGroupData.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/ResourceGroupData.cs index 175310efcb45..a653c6282620 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/ResourceGroupData.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/ResourceGroupData.cs @@ -10,7 +10,7 @@ namespace Azure.ResourceManager.Core /// /// A class representing the ResourceGroup data model. /// - public class ResourceGroupData : TrackedResource + public class ResourceGroupData : TrackedResource { /// /// Initializes a new instance of the class. diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/SubscriptionData.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/SubscriptionData.cs index be3b12feeb18..922bff84bc54 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/SubscriptionData.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Placeholder/SubscriptionData.cs @@ -9,7 +9,7 @@ namespace Azure.ResourceManager.Core /// /// A class representing the subscription data model. /// - public class SubscriptionData : Resource + public class SubscriptionData : Resource { /// /// Initializes a new instance of the class. @@ -23,7 +23,7 @@ public SubscriptionData(ResourceManager.Resources.Models.Subscription subscripti State = subscription.State; SubscriptionPolicies = subscription.SubscriptionPolicies; AuthorizationSource = subscription.AuthorizationSource; - Id = subscription.Id; + Id = new SubscriptionResourceIdentifier(subscription.Id); ManagedByTenants = subscription.ManagedByTenants; Tags = subscription.Tags; } @@ -59,7 +59,7 @@ public SubscriptionData(ResourceManager.Resources.Models.Subscription subscripti public string AuthorizationSource { get; } /// - public override ResourceIdentifier Id { get; protected set; } + public override SubscriptionResourceIdentifier Id { get; protected set; } /// /// Gets an array containing the tenants managing the subscription. diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceContainerBase.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceContainerBase.cs index ec896f0f26b4..62d0eefc945f 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceContainerBase.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceContainerBase.cs @@ -10,24 +10,26 @@ namespace Azure.ResourceManager.Core /// /// A class representing collection of resources and their operations over their parent. /// + /// The type of the resource identifier. /// The type of the class containing operations for the underlying resource. /// The type of the class containing properties for the underlying resource. - public abstract class ResourceContainerBase : ContainerBase - where TOperations : ResourceOperationsBase - where TResource : Resource + public abstract class ResourceContainerBase : ContainerBase + where TOperations : ResourceOperationsBase + where TResource : Resource + where TIdentifier : TenantResourceIdentifier { private static readonly object _parentLock = new object(); private object _parentResource; /// - /// Initializes a new instance of the class for mocking. + /// Initializes a new instance of the class for mocking. /// protected ResourceContainerBase() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The resource representing the parent resource. protected ResourceContainerBase(ResourceOperationsBase parent) @@ -42,8 +44,8 @@ protected ResourceContainerBase(ResourceOperationsBase parent) /// Resource identifier is not a valid type for this container. protected override void Validate(ResourceIdentifier identifier) { - if (identifier.Type != ValidResourceType) - throw new InvalidOperationException($"{identifier.Type} is not a valid container for {Id.Type}"); + if (identifier.ResourceType != ValidResourceType) + throw new InvalidOperationException($"{identifier.ResourceType} is not a valid container for {Id.ResourceType}"); } /// @@ -112,11 +114,13 @@ public abstract Task> StartCreateOrUpdateAsync( /// Gets the location of the parent object. /// /// The type of the parents full resource object. + /// The type of the parents resource id. /// The type of the parents operations object. /// The associated with the parent object. - protected TParent GetParentResource() + protected TParent GetParentResource() where TParent : TParentOperations - where TParentOperations : ResourceOperationsBase + where TParentOperations : ResourceOperationsBase + where TParentId : ResourceIdentifier { if (_parentResource is null) { diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupContainer.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupContainer.cs index 4f4441eb1bdb..5a88837c374b 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupContainer.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupContainer.cs @@ -13,7 +13,7 @@ namespace Azure.ResourceManager.Core /// /// A class representing collection of ResourceGroupContainer and their operations over a ResourceGroup. /// - public class ResourceGroupContainer : ResourceContainerBase + public class ResourceGroupContainer : ResourceContainerBase { /// /// Initializes a new instance of the class for mocking. @@ -34,11 +34,20 @@ internal ResourceGroupContainer(SubscriptionOperations subscription) /// protected override ResourceType ValidResourceType => SubscriptionOperations.ResourceType; - private ResourceGroupsOperations Operations => new ResourcesManagementClient( - BaseUri, - Id.Subscription, - Credential, - ClientOptions.Convert()).ResourceGroups; + private ResourceGroupsOperations Operations + { + get + { + string subscriptionId; + if (Id is null || !Id.TryGetSubscriptionId(out subscriptionId)) + subscriptionId = Guid.NewGuid().ToString(); + return new ResourcesManagementClient( + BaseUri, + subscriptionId, + Credential, + ClientOptions.Convert()).ResourceGroups; + } + } /// /// Constructs an object used to create a resource group. @@ -48,7 +57,7 @@ internal ResourceGroupContainer(SubscriptionOperations subscription) /// Who the resource group is managed by. /// A builder with and . /// Location cannot be null. - public ArmBuilder Construct(LocationData location, IDictionary tags = default, string managedBy = default) + public ArmBuilder Construct(LocationData location, IDictionary tags = default, string managedBy = default) { if (location is null) throw new ArgumentNullException(nameof(location)); @@ -57,7 +66,7 @@ public ArmBuilder Construct(LocationData locat if (!(tags is null)) model.Tags.ReplaceWith(tags); model.ManagedBy = managedBy; - return new ArmBuilder(this, new ResourceGroupData(model)); + return new ArmBuilder(this, new ResourceGroupData(model)); } /// diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupOperations.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupOperations.cs index d5057ad8fa90..bfad3556ff1e 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupOperations.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceGroupOperations.cs @@ -15,13 +15,13 @@ namespace Azure.ResourceManager.Core /// /// A class representing the operations that can be performed over a specific ResourceGroup. /// - public class ResourceGroupOperations : ResourceOperationsBase, - ITaggableResource, IDeletableResource + public class ResourceGroupOperations : ResourceOperationsBase, + ITaggableResource, IDeletableResource { /// /// Gets the resource type definition for a ResourceType. /// - public static readonly ResourceType ResourceType = "Microsoft.Resources/resourceGroups"; + public static readonly ResourceType ResourceType = "Microsoft.Resources/subscriptions/resourceGroups"; /// /// Initializes a new instance of the class for mocking. @@ -36,7 +36,7 @@ protected ResourceGroupOperations() /// The client parameters to use in these operations. /// The name of the resource group to use. internal ResourceGroupOperations(SubscriptionOperations options, string rgName) - : base(options, $"{options.Id}/resourceGroups/{rgName}") + : base(options, new ResourceGroupResourceIdentifier(options.Id, rgName)) { if (rgName.Length > 90) throw new ArgumentOutOfRangeException(nameof(rgName), "ResourceGroupName cannot be longer than 90 characters."); @@ -52,7 +52,7 @@ internal ResourceGroupOperations(SubscriptionOperations options, string rgName) /// /// The client parameters to use in these operations. /// The identifier of the resource that is the target of operations. - protected ResourceGroupOperations(ResourceOperationsBase options, ResourceIdentifier id) + protected ResourceGroupOperations(ResourceOperationsBase options, ResourceGroupResourceIdentifier id) : base(options, id) { } @@ -62,7 +62,7 @@ protected ResourceGroupOperations(ResourceOperationsBase options, ResourceIdenti private ResourceGroupsOperations Operations => new ResourcesManagementClient( BaseUri, - Id.Subscription, + Id.SubscriptionId, Credential, ClientOptions.Convert()).ResourceGroups; @@ -316,21 +316,23 @@ await Operations.UpdateAsync(Id.Name, patch, cancellationToken).ConfigureAwait(f /// The model representing the object to create. />. /// The type of the class containing the container for the specific resource. /// The type of the operations class for a specific resource. + /// The type of the resource identifier. /// The type of the class containing properties for the underlying resource. /// Returns a response with the operation for this resource. /// Name cannot be null or a whitespace. /// Model cannot be null. - public virtual ArmResponse CreateResource(string name, TResource model) - where TResource : TrackedResource - where TOperations : ResourceOperationsBase - where TContainer : ResourceContainerBase + public virtual ArmResponse CreateResource(string name, TResource model) + where TResource : TrackedResource + where TOperations : ResourceOperationsBase + where TContainer : ResourceContainerBase + where TIdentifier : SubscriptionResourceIdentifier { if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException($"{nameof(name)} provided cannot be null or a whitespace.", nameof(name)); if (model is null) throw new ArgumentNullException(nameof(model)); - var myResource = model as TrackedResource; + var myResource = model as TrackedResource; TContainer container = Activator.CreateInstance(typeof(TContainer), ClientOptions, myResource) as TContainer; return container.CreateOrUpdate(name, model); @@ -343,22 +345,24 @@ public virtual ArmResponse CreateResource The model representing the object to create. />. /// A token to allow the caller to cancel the call to the service. The default value is . /// The type of the class containing the container for the specific resource. - /// The type of the operations class for a specific resource. + /// The type of the operations class for a specific resource. + /// The type of the resource identifier. /// The type of the class containing properties for the underlying resource. /// A that on completion returns a response with the operation for this resource. /// Name cannot be null or a whitespace. /// Model cannot be null. - public virtual Task> CreateResourceAsync(string name, TResource model, CancellationToken cancellationToken = default) - where TResource : TrackedResource - where TOperations : ResourceOperationsBase - where TContainer : ResourceContainerBase + public virtual Task> CreateResourceAsync(string name, TResource model, CancellationToken cancellationToken = default) + where TResource : TrackedResource + where TOperations : ResourceOperationsBase + where TContainer : ResourceContainerBase + where TIdentifier : SubscriptionResourceIdentifier { if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException($"{nameof(name)} provided cannot be null or a whitespace.", nameof(name)); if (model is null) throw new ArgumentNullException(nameof(model)); - var myResource = model as TrackedResource; + var myResource = model as TrackedResource; TContainer container = Activator.CreateInstance(typeof(TContainer), ClientOptions, myResource) as TContainer; diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceListOperations.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceListOperations.cs index 469af5edd69b..8217e11ec8c1 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceListOperations.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceListOperations.cs @@ -107,7 +107,8 @@ public static AsyncPageable ListAtContextAsync( private static ResourcesManagementClient GetResourcesClient(ResourceOperationsBase resourceOperations) { - return new ResourcesManagementClient(resourceOperations.BaseUri, resourceOperations.Id.Subscription, resourceOperations.Credential); + var subscription = resourceOperations.Id as SubscriptionResourceIdentifier; + return new ResourcesManagementClient(resourceOperations.BaseUri, subscription?.SubscriptionId, resourceOperations.Credential); } private static AsyncPageable ListAtContextInternalAsync( diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceOperationsBase.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceOperationsBase.cs index 429da52c7e4e..6f5cd988b505 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceOperationsBase.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/ResourceOperationsBase.cs @@ -23,6 +23,15 @@ protected ResourceOperationsBase() { } + /// + /// Initializes a new instance of the class. + /// + /// The generic operations representing the resource + protected ResourceOperationsBase(GenericResourceOperations operations) + : base(operations.ClientOptions, operations.Id, operations.Credential, operations.BaseUri) + { + } + /// /// Initializes a new instance of the class. /// @@ -59,19 +68,20 @@ protected ResourceOperationsBase(AzureResourceManagerClientOptions options, Reso /// Base class for all operations over a resource /// /// The type implementing operations over the resource. + /// The The identifier type for the resource. [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Types differ by type argument only")] - public abstract class ResourceOperationsBase : ResourceOperationsBase - where TOperations : ResourceOperationsBase + public abstract class ResourceOperationsBase : ResourceOperationsBase + where TOperations : ResourceOperationsBase where TIdentifier : ResourceIdentifier { /// - /// Initializes a new instance of the class for mocking. + /// Initializes a new instance of the class for mocking. /// protected ResourceOperationsBase() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Generic ARMResourceOperations for this resource type. protected ResourceOperationsBase(GenericResourceOperations genericOperations) @@ -80,7 +90,7 @@ protected ResourceOperationsBase(GenericResourceOperations genericOperations) } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The resource representing the parent resource. /// The identifier of the resource that is the target of operations. @@ -90,7 +100,7 @@ protected ResourceOperationsBase(ResourceOperationsBase parentOperations, Resour } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The client parameters to use in these operations. /// The identifier of the resource that is the target of operations. @@ -101,6 +111,14 @@ protected ResourceOperationsBase(AzureResourceManagerClientOptions options, Reso { } + /// + /// The typed resource identifier for the underlying resource + /// + public virtual new TIdentifier Id + { + get { return base.Id as TIdentifier; } + } + /// /// Gets details for this resource from the service. /// diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationContainer.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationContainer.cs index a87b0120127c..2b7133da62d5 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationContainer.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationContainer.cs @@ -20,6 +20,7 @@ public class LocationContainer : OperationsBase internal LocationContainer(SubscriptionOperations subscriptionOperations) : base(subscriptionOperations.ClientOptions, subscriptionOperations.Id, subscriptionOperations.Credential, subscriptionOperations.BaseUri) { + Id = subscriptionOperations.Id; } /// @@ -30,6 +31,11 @@ internal LocationContainer(SubscriptionOperations subscriptionOperations) /// private SubscriptionsOperations SubscriptionsClient => ResourcesClient.Subscriptions; + /// + /// The resource id + /// + public new SubscriptionResourceIdentifier Id { get; } + /// /// Gets the Azure subscriptions. /// @@ -45,7 +51,7 @@ public SubscriptionContainer GetSubscriptionContainer() /// A collection of location data that may take multiple service requests to iterate over. public Pageable List() { - return new PhWrappingPageable(SubscriptionsClient.ListLocations(Id.Subscription), s => s.DisplayName); + return new PhWrappingPageable(SubscriptionsClient.ListLocations(Id.SubscriptionId), s => s.DisplayName); } /// @@ -55,7 +61,7 @@ public Pageable List() /// An async collection of location data that may take multiple service requests to iterate over. public AsyncPageable ListAsync(CancellationToken token = default(CancellationToken)) { - return new PhWrappingAsyncPageable(SubscriptionsClient.ListLocationsAsync(Id.Subscription, token), s => s.DisplayName); + return new PhWrappingAsyncPageable(SubscriptionsClient.ListLocationsAsync(Id.SubscriptionId, token), s => s.DisplayName); } } } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationResourceIdentifier.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationResourceIdentifier.cs new file mode 100644 index 000000000000..900b34fe0163 --- /dev/null +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/LocationResourceIdentifier.cs @@ -0,0 +1,101 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Azure.ResourceManager.Core +{ + /// + /// The identifier for a resource that is contained in a location. + /// + public sealed class LocationResourceIdentifier : SubscriptionResourceIdentifier + { + /// + /// Initializes a new instance of the class. + /// + /// The identifier of the subscription that is the parent of this resource. + /// The name of the location. + internal LocationResourceIdentifier(SubscriptionResourceIdentifier parent, LocationData location) + : base(parent, ResourceIdentifier.LocationsKey, location.Name) + { + Location = location; + } + + /// + /// Initializes a new instance of the class. + /// + /// A string representation of a location resource identifier. + public LocationResourceIdentifier(string resourceId) + { + var id = ResourceIdentifier.Create(resourceId) as LocationResourceIdentifier; + if (id is null) + throw new ArgumentException("Not a valid location level resource", nameof(resourceId)); + Name = id.Name; + ResourceType = id.ResourceType; + Parent = id.Parent; + IsChild = id.IsChild; + Location = id.Location; + SubscriptionId = id.SubscriptionId; + } + + /// + /// Initializes a new instance of the class. + /// Used to initialize resources in the same namespace as the parent resource. + /// + /// + /// + /// + internal LocationResourceIdentifier(LocationResourceIdentifier parent, string resourceType, string resourceName) + : base(parent, resourceType, resourceName) + { + Location = parent.Location; + } + + /// + /// Initializes a new instance of the class. + /// Used to initialize resource in a different namespace than the parent resource. + /// + /// The identifier of the parent resource. + /// The namespace of the resource, for example 'Microsoft.Compute'. + /// The simple type name of the resource, for example 'virtualMachines'. + /// The name of this resource. + internal LocationResourceIdentifier(LocationResourceIdentifier target, string providerNamespace, string resourceType, string resourceName) + : base(target, providerNamespace, resourceType, resourceName) + { + Location = target.Location; + } + + /// + /// The location of the resource. + /// + public LocationData Location { get; } + + /// + public override bool TryGetLocation(out LocationData location) + { + location = Location; + return true; + } + + /// + public override bool TryGetSubscriptionId(out string subscriptionId) + { + subscriptionId = SubscriptionId; + return true; + } + + /// + /// Convert resourceId string to LocationResourceIdentifier. + /// + /// A string representation of a resource id. + public static implicit operator LocationResourceIdentifier(string other) + { + if (other is null) + return null; + LocationResourceIdentifier id = ResourceIdentifier.Create(other) as LocationResourceIdentifier; + if (id is null) + throw new ArgumentException("Not a valid location level resource", nameof(other)); + return id; + } + } +} diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/Resource.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/Resource.cs index 961546c1cbef..81faffdf9533 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/Resource.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/Resource.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -9,13 +9,13 @@ namespace Azure.ResourceManager.Core /// A class representing the base resource used by all azure resources. /// [ReferenceType] - public abstract class Resource : IEquatable, IEquatable, IComparable, - IComparable + public abstract class Resource : IEquatable>, IEquatable, + IComparable>, IComparable where TIdentifier : TenantResourceIdentifier { /// /// Gets or sets the resource identifier. /// - public virtual ResourceIdentifier Id { get; protected set; } + public virtual TIdentifier Id { get; protected set; } /// /// Gets the name. @@ -25,10 +25,10 @@ public abstract class Resource : IEquatable, IEquatable, IComp /// /// Gets the resource type. /// - public virtual ResourceType Type => Id?.Type; + public virtual ResourceType Type => Id?.ResourceType; /// - public virtual int CompareTo(Resource other) + public virtual int CompareTo(Resource other) { if (other == null) return 1; @@ -48,11 +48,11 @@ public virtual int CompareTo(Resource other) /// public virtual int CompareTo(string other) { - return string.Compare(Id?.Id, other, StringComparison.InvariantCultureIgnoreCase); + return string.Compare(Id, other, StringComparison.InvariantCultureIgnoreCase); } /// - public virtual bool Equals(Resource other) + public virtual bool Equals(Resource other) { if (Id == null) return false; diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceGroupResourceIdentifier.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceGroupResourceIdentifier.cs new file mode 100644 index 000000000000..6f223de9029a --- /dev/null +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceGroupResourceIdentifier.cs @@ -0,0 +1,96 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Azure.ResourceManager.Core +{ + /// + /// The identifier for a resource contained in a resource group. + /// + public sealed class ResourceGroupResourceIdentifier : SubscriptionResourceIdentifier + { + /// + /// Initializes a new instance of the class for a resource group. + /// + /// The of the parent of this child resource. + /// The name of the resourceGroup. + internal ResourceGroupResourceIdentifier(SubscriptionResourceIdentifier parent, string resourceGroupName) + : base(parent, ResourceIdentifier.ResourceGroupsKey, resourceGroupName) + { + if (string.IsNullOrWhiteSpace(resourceGroupName)) + throw new ArgumentOutOfRangeException(nameof(resourceGroupName), "Invalid resource group name."); + ResourceGroupName = resourceGroupName; + } + + /// + /// Initializes a new instance of the class + /// for a resource in a different namespace than its parent. + /// + /// he of the target of this extension resource. + /// The provider namespace of the extension. + /// The full ARM resource type of the extension. + /// The name of the extension resource. + internal ResourceGroupResourceIdentifier(ResourceGroupResourceIdentifier target, string providerNamespace, string resourceType, string resourceName) + : base(target, providerNamespace, resourceType, resourceName) + { + ResourceGroupName = target.ResourceGroupName; + } + + /// + /// Initializes a new instance of the class + /// for a resource in the same namespace as its parent. + /// + /// he of the target of this extension resource. + /// The full ARM resource type of the extension. + /// The name of the extension resource. + internal ResourceGroupResourceIdentifier(ResourceGroupResourceIdentifier target, string childResourceType, string childResourceName) + : base(target, childResourceType, childResourceName) + { + ResourceGroupName = target.ResourceGroupName; + } + + /// + /// Initializes a new instance of the class + /// + /// The string representation of a resource id. + public ResourceGroupResourceIdentifier(string resourceId) + { + var id = ResourceIdentifier.Create(resourceId) as ResourceGroupResourceIdentifier; + if (id is null) + throw new ArgumentException("Not a valid tenant level resource", nameof(resourceId)); + Name = id.Name; + ResourceType = id.ResourceType; + Parent = id.Parent; + IsChild = id.IsChild; + ResourceGroupName = id.ResourceGroupName; + SubscriptionId = id.SubscriptionId; + } + + /// + /// The name of the resource group for this resource. + /// + public string ResourceGroupName { get; } + + /// + public override bool TryGetResourceGroupName(out string resourceGroupName) + { + resourceGroupName = ResourceGroupName; + return true; + } + + /// + /// Convert a string into a resource group resource identifier. + /// + /// The string representation of a resource Id. + public static implicit operator ResourceGroupResourceIdentifier(string other) + { + if (other is null) + return null; + ResourceGroupResourceIdentifier id = ResourceIdentifier.Create(other) as ResourceGroupResourceIdentifier; + if (id is null) + throw new ArgumentException("Not a valid resource group level resource", nameof(other)); + return id; + } + } +} diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifier.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifier.cs index 71caa38ee72f..4c19a5cf59b0 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifier.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifier.cs @@ -3,295 +3,448 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; +using System.Text; namespace Azure.ResourceManager.Core { /// - /// Canonical Representation of a Resource Identity. + /// An Azure Resource Manager resource identifier. /// - public sealed class ResourceIdentifier : - IEquatable, - IEquatable, - IComparable, - IComparable + public abstract class ResourceIdentifier : IEquatable, IComparable { - private readonly IDictionary _partsDictionary = - new Dictionary(StringComparer.OrdinalIgnoreCase); + internal const string ProvidersKey = "providers", SubscriptionsKey = "subscriptions", + ResourceGroupsKey = "resourceGroups", LocationsKey = "locations"; + + internal const string ResourceGroupsLowerKey = "resourcegroups"; + + internal const string BuiltInResourceNamespace = "Microsoft.Resources"; + + internal static ResourceType SubscriptionType => new ResourceType(BuiltInResourceNamespace, SubscriptionsKey); + internal static ResourceType LocationsType => + new ResourceType(BuiltInResourceNamespace, $"{SubscriptionsKey}/{LocationsKey}"); + internal static ResourceType ResourceGroupsType => + new ResourceType(BuiltInResourceNamespace, $"{SubscriptionsKey}/{ResourceGroupsKey}"); /// - /// Initializes a new instance of the class. + /// The root of the resource hierarchy + /// + public static ResourceIdentifier RootResourceIdentifier => new RootResourceIdentifier(); + + /// + /// For internal use only. /// - /// The identifier of the resource that is the target of operations. - public ResourceIdentifier(string id) + internal ResourceIdentifier() { - Id = id; - Parse(id); + _stringValue = null; } /// - /// Gets the Resource ID. + /// For internal use only. /// - public string Id { get; private set; } + /// The type of the resource. + /// The name of the resource. + internal ResourceIdentifier(ResourceType resourceType, string name) + { + ResourceType = resourceType; + Name = name; + _stringValue = null; + } /// - /// Gets the Resource Name. + /// Initializes a new instance of the class. /// - public string Name { get; private set; } + /// The string representation of a resource Id. + /// The resource identifier. + public static ResourceIdentifier Create(string resourceId) + { + if (resourceId is null) + throw new ArgumentNullException(nameof(resourceId)); + if (!resourceId.StartsWith("/", StringComparison.InvariantCultureIgnoreCase)) + throw new ArgumentOutOfRangeException(nameof(resourceId), "Invalid resource id."); + var parts = resourceId.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).ToList(); + if (parts.Count < 2) + throw new ArgumentOutOfRangeException(nameof(resourceId), "Invalid resource id."); + switch (parts[0].ToLowerInvariant()) + { + case SubscriptionsKey: + { + ResourceIdentifier id = CreateBaseSubscriptionIdentifier(parts[1], parts.Trim(2)); + id.StringValue = resourceId; + return id; + } + case ProvidersKey: + { + if (parts.Count > 3) + { + ResourceIdentifier id = CreateTenantIdentifier(new TenantResourceIdentifier(new ResourceType(parts[1], parts[2]), parts[3]), parts.Trim(4)); + id.StringValue = resourceId; + return id; + } + throw new ArgumentOutOfRangeException(nameof(resourceId), "Invalid resource id."); + } + default: + throw new ArgumentOutOfRangeException(nameof(resourceId), "Invalid resource id."); + } + } /// - /// Gets the Resource Type. + /// Create a new instance of the class for resource identifiers + /// that are contained in a subscription. /// - public ResourceType Type { get; private set; } + /// The GUID string representing the resource. + /// The path segments in the resource id following the subscription Guid. + /// The resource identifier for the given resource path. + internal static ResourceIdentifier CreateBaseSubscriptionIdentifier(string subscriptionId, List parts) + { + Guid subscriptionGuid; + if (!Guid.TryParse(subscriptionId, out subscriptionGuid)) + throw new ArgumentOutOfRangeException(nameof(subscriptionId), "Invalid subscription id."); + var subscription = new SubscriptionResourceIdentifier( subscriptionGuid); + if (parts.Count == 0) + return subscription; + if (parts.Count > 1) + { + switch (parts[0].ToLowerInvariant()) + { + case LocationsKey: + return CreateBaseLocationIdentifier(subscription, parts[1], parts.Trim(2)); + case ResourceGroupsLowerKey: + return CreateBaseResourceGroupIdentifier(subscription, parts[1], parts.Trim(2)); + case ProvidersKey: + { + if (parts.Count > 3) + return CreateSubscriptionIdentifier(new SubscriptionResourceIdentifier(subscription, + parts[1], parts[2], parts[3]), parts.Skip(4).ToList()); + throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource string"); + } + default: + { + throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id."); + } + } + } + + throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id."); + } /// - /// Gets the Subscription. + /// Create a new instance of the class for resource identifiers + /// that are contained in a location. /// - public string Subscription => _partsDictionary.ContainsKey(KnownKeys.Subscription) - ? _partsDictionary[KnownKeys.Subscription] - : null; + /// The resource id of the subscription for this resource. + /// The location of the resource. + /// The path segments in the resource id following the location. + /// The resource identifier for the given resource path. + internal static ResourceIdentifier CreateBaseLocationIdentifier(SubscriptionResourceIdentifier subscription, LocationData location, List parts) + { + var parent = new LocationResourceIdentifier(subscription, location); + if (parts.Count == 0) + return parent; + if (parts.Count == 1) + throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id."); + switch (parts[0].ToLowerInvariant()) + { + case ProvidersKey: + { + if (parts.Count > 3) + return CreateLocationIdentifier(new LocationResourceIdentifier(parent, parts[1], parts[2], parts[3]), parts.Trim(4)); + throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id."); + } + default: + return CreateLocationIdentifier(new LocationResourceIdentifier(parent, parts[0], parts[1]), parts.Trim(2)); + } + } /// - /// Gets the Resource Group. + /// Create a new instance of the class for resource identifiers + /// that are contained in a resource group. /// - public string ResourceGroup => _partsDictionary.ContainsKey(KnownKeys.ResourceGroup) - ? _partsDictionary[KnownKeys.ResourceGroup] - : null; + /// The resource id of the subscription for this resource. + /// The resource group containing the resource. + /// The path segments in the resource id following the resource group name. + /// The resource identifier for the given resource path. + internal static ResourceIdentifier CreateBaseResourceGroupIdentifier(SubscriptionResourceIdentifier subscription, string resourceGroupName, List parts) + { + var parent = new ResourceGroupResourceIdentifier(subscription, resourceGroupName); + if (parts.Count == 0) + return parent; + if (parts.Count == 1) + throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id."); + switch (parts[0].ToLowerInvariant()) + { + case ProvidersKey: + { + if (parts.Count > 3) + return CreateResourceGroupIdentifier(new ResourceGroupResourceIdentifier(parent, parts[1], parts[2], parts[3]), parts.Trim(4)); + throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id."); + } + default: + throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id."); + } + } /// - /// Gets the Parent. - /// Currently this will contain the identifier for either the parent resource, the resource group, the location, the subscription, or the tenant that is the logical parent of this resource. + /// Create a new instance of the class for resource identifiers + /// that are based in the tenant. /// - public ResourceIdentifier Parent { get; private set; } + /// The resource id of the parent resource. + /// The path segments in the resource path after the parent. + /// A resource identifier for a resource contained in the tenant. + internal static ResourceIdentifier CreateTenantIdentifier(TenantResourceIdentifier parent, List parts) + { + if (parts.Count == 0) + return parent; + if (parts.Count == 1) + return new TenantResourceIdentifier(parent, parts[0], string.Empty); + if (parts.Count > 3 && string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase)) + return CreateTenantIdentifier(new TenantResourceIdentifier(parent, parts[1], parts[2], parts[3]), parts.Trim(4)); + if (parts.Count > 1 && !string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase)) + return CreateTenantIdentifier(new TenantResourceIdentifier(parent, parts[0], parts[1]), parts.Trim(2)); + throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id."); + } /// - /// Initializes a new instance of the class from a string. + /// Create a new instance of the class for resource identifiers + /// that are based in a subscription. /// - /// String to be implicit converted into a object. - public static implicit operator ResourceIdentifier(string other) + /// The resource id of the parent resource. + /// The path segments in the resource path after the parent. + /// A resource identifier for a resource contained in the subscription. + internal static ResourceIdentifier CreateSubscriptionIdentifier(SubscriptionResourceIdentifier parent, List parts) { - if (other is null) - return null; - - return new ResourceIdentifier(other); + if (parts.Count == 0) + return parent; + if (parts.Count == 1) + return new SubscriptionResourceIdentifier(parent, parts[0], string.Empty); + if (parts.Count > 3 && string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase)) + return CreateSubscriptionIdentifier(new SubscriptionResourceIdentifier(parent, parts[1], parts[2], parts[3]), parts.Trim(4)); + if (parts.Count > 1 && !string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase)) + return CreateSubscriptionIdentifier(new SubscriptionResourceIdentifier(parent, parts[0], parts[1]), parts.Trim(2)); + throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id."); } /// - /// Creates a new string from a object. + /// Create a new instance of the class for resource identifiers + /// that are contained in a location. /// - /// object to be implicit converted into an string. - public static implicit operator string(ResourceIdentifier other) + /// The resource id of the parent resource. + /// The path segments in the resource path after the parent. + /// A resource identifier for a resource contained in a location. + internal static ResourceIdentifier CreateLocationIdentifier(LocationResourceIdentifier parent, List parts) { - if (other is null) - return null; - - return other.Id; + if (parts.Count == 0) + return parent; + if (parts.Count == 1) + return new LocationResourceIdentifier(parent, parts[0], string.Empty); + if (parts.Count > 3 && string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase)) + return CreateLocationIdentifier(new LocationResourceIdentifier(parent, parts[1], parts[2], parts[3]), parts.Trim(4)); + if (parts.Count > 1 && !string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase)) + return CreateLocationIdentifier(new LocationResourceIdentifier(parent, parts[0], parts[1]), parts.Trim(2)); + throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id."); } /// - /// Allow static, safe comparisons of resource identifier strings or objects. + /// Create a new instance of the class for resource identifiers + /// that are contained in a resource group. /// - /// A resource id. - /// Another resource id. - /// True if the resource ids are equivalent, otherwise False. - public static bool Equals(ResourceIdentifier x, ResourceIdentifier y) + /// The resource id of the parent resource. + /// The path segments in the resource path after the parent. + /// A resource identifier for a resource contained in a resource group. + internal static ResourceIdentifier CreateResourceGroupIdentifier(ResourceGroupResourceIdentifier parent, List parts) { - if (null == x && null == y) - return true; - - if (null == x || null == y) - return false; - - return x.Equals(y); + if (parts.Count == 0) + return parent; + if (parts.Count == 1) + return new ResourceGroupResourceIdentifier(parent, parts[0], string.Empty); + if (parts.Count > 3 && string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase)) + return CreateResourceGroupIdentifier(new ResourceGroupResourceIdentifier(parent, parts[1], parts[2], parts[3]), parts.Trim(4)); + if (parts.Count > 1 && !string.Equals(parts[0], ProvidersKey, StringComparison.InvariantCultureIgnoreCase)) + return CreateResourceGroupIdentifier(new ResourceGroupResourceIdentifier(parent, parts[0], parts[1]), parts.Trim(2)); + throw new ArgumentOutOfRangeException(nameof(parts), "Invalid resource id."); } + private object lockObject = new object(); + private string _stringValue; + /// - /// Allow static null-safe comparisons between resource identifier strings or objects. + /// Cache the string representation of this resource, so traversal only needs to occur once. /// - /// A resource id. - /// Another resource id. - /// -1 if x < y, 0 if x == y, 1 if x > y. - public static int CompareTo(ResourceIdentifier x, ResourceIdentifier y) + internal string StringValue { - if (null == x && null == y) - return 0; + get + { + lock (lockObject) + { + if (_stringValue is null) + { + _stringValue = ToResourceString(); + } + + return _stringValue; + } + } - if (null == x) - return -1; + set + { + lock (lockObject) + { + _stringValue = value; + } + } + } - if (null == y) - return 1; + /// + /// The resource type of the resource. + /// + public virtual ResourceType ResourceType { get; internal set; } - return x.CompareTo(y); - } + /// + /// The name of the resource. + /// + public virtual string Name { get; internal set; } - /// - public override int GetHashCode() - { - return Id.GetHashCode(); - } + /// + /// The immediate parent containing this resource. + /// + public virtual ResourceIdentifier Parent { get; internal set; } - /// - public override string ToString() - { - return Id; - } + /// + /// Determines whether this resource is in the same namespace as its parent. + /// + internal virtual bool IsChild { get; set; } /// - /// Compares this instance ID with another instance's ID. + /// Tries to get the resource identifier of the parent of this resource. /// - /// object to compare. - /// -1 for less than, 0 for equals, 1 for greater than. - public int CompareTo(ResourceIdentifier other) + /// The resource id of the parent resource. + /// True if the resource has a parent, otherwise false. + public virtual bool TryGetParent(out ResourceIdentifier containerId) { - return string.Compare( - Id?.ToLowerInvariant(), - other?.Id?.ToLowerInvariant(), - StringComparison.InvariantCultureIgnoreCase); + containerId = default(ResourceIdentifier); + if (this.Parent is RootResourceIdentifier) + return false; + containerId = this.Parent; + return true; } /// - /// Compares this instance ID with another plain text ID. + /// Tries to get the subscription associated with this resource. /// - /// The ID to compare. - /// -1 for less than, 0 for equals, 1 for greater than. - public int CompareTo(string other) + /// The resource Id of the subscription for this resource. + /// True if the resource is contained in a subscription, otherwise false. + public virtual bool TryGetSubscriptionId(out string subscriptionId) { - return string.Compare( - Id?.ToLowerInvariant(), - other?.ToLowerInvariant(), - StringComparison.InvariantCultureIgnoreCase); + subscriptionId = default(string); + return false; } /// - /// Compares this instance ID with another instance's ID and determines if they are equals. + /// Tries to get the resource group associated with this resource. /// - /// object to compare. - /// True if they are equals, otherwise false. - public bool Equals(ResourceIdentifier other) + /// The resource group for this resource. + /// True if the resource is contained in a resource group, otherwise false. + public virtual bool TryGetResourceGroupName(out string resourceGroupName) { - return string.Equals( - Id?.ToLowerInvariant(), - other?.Id?.ToLowerInvariant(), - StringComparison.InvariantCultureIgnoreCase); + resourceGroupName = default(string); + return false; } /// - /// Compares this instance ID with another plain text ID. and determines if they are equals. + /// Tries to get the location associated with this resource. /// - /// The ID to compare. - /// True if they are equals, otherwise false. - public bool Equals(string other) + /// The location for thsi resource. + /// True if the resource is contained in a location, otherwise false. + public virtual bool TryGetLocation(out LocationData location) { - return string.Equals( - Id?.ToLowerInvariant(), - other?.ToLowerInvariant(), - StringComparison.InvariantCultureIgnoreCase); + location = default(LocationData); + return false; } /// - /// Populate Resource Identity fields from input string. + /// Create the resource id string based on the resource id string of the parent resource. /// - /// A properly formed resource identity. - private void Parse(string id) + /// The string representation of this resource id. + internal virtual string ToResourceString() { - // Throw for null, empty, and string without the correct form - if (string.IsNullOrWhiteSpace(id) || !id.Contains('/')) - throw new ArgumentOutOfRangeException($"'{id}' is not a valid resource"); - - // Resource ID paths consist mainly of name/value pairs. Split the uri so we have an array of name/value pairs - var parts = id.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).ToList(); - // There must be at least one name/value pair for the resource id to be valid - if (parts.Count < 2 && !KnownKeys.Tenant.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase)) - throw new ArgumentOutOfRangeException($"'{id}' is not a valid resource"); - - // This is asserting that resources must start with '/subscriptions', /tenants, or /locations. - // TODO: we will need to update this code to accomodate tenant based resources (which start with /providers) - if (!KnownKeys.Subscription.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase) && - !KnownKeys.Tenant.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase) && - !KnownKeys.ProviderNamespace.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase) && - !KnownKeys.Location.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase)) + StringBuilder builder = new StringBuilder(Parent.ToResourceString()); + if (IsChild) { - throw new ArgumentOutOfRangeException($"'{id}' is not a valid resource"); + builder.Append($"/{ResourceType.Types.Last()}"); + if (!string.IsNullOrWhiteSpace(Name)) + builder.Append($"/{Name}"); } - - Type = new ResourceType(id); - - // In the case that this resource is a singleton proxy resource, the number of parts will be odd, - // where the last part is the type name of the singleton - if (parts.Count % 2 != 0 && !KnownKeys.Tenant.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase)) + else { - _partsDictionary.Add(KnownKeys.UntrackedSubResource, parts.Last()); - parts.RemoveAt(parts.Count - 1); + builder.Append($"/providers/{ResourceType.Namespace}/{ResourceType.Type}/{Name}"); } - // This spplits into resource that come from a provider (which have the providers keyword) and - // resources that are built in to ARM (e.g. /subscriptions/{sub}, /subscriptions/{sub}/resourceGroups/{rg}) - // TODO: This code will need to be updates for extension resources, which have two providers - if (id.ToLowerInvariant().Contains("providers")) - { - ParseProviderResource(parts); - } - else if (!KnownKeys.Tenant.Equals(parts[0], StringComparison.InvariantCultureIgnoreCase)) - { - ParseGenericResource(parts); - } + return builder.ToString(); } /// - /// Helper method to parse a built in resource. + /// Return the string representation of the resource identifier. /// - /// Resource ID paths consisting of name/value pairs. - private void ParseGenericResource(IList parts) + /// The string representation of this resource identifier. + public override string ToString() { - Debug.Assert(parts != null, "Parts parameter is null."); - Debug.Assert(parts.Count > 1, "Parts should be a list containing more than 1 elements."); - - // The resource consists of well-known name-value pairs. Make a resource dictionary - // using the names as keys, and the values as values - for (var i = 0; i < parts.Count - 1; i += 2) - { - _partsDictionary.Add(parts[i], parts[i + 1]); - } - - // resource name is always the last part - Name = parts.Last(); - parts.RemoveAt(parts.Count - 1); - parts.RemoveAt(parts.Count - 1); + return StringValue; + } - // remove the last key/value pair to arrive at the parent (Count will be zero for /subscriptions/{foo}) - Parent = parts.Count > 1 ? new ResourceIdentifier($"/{string.Join("/", parts)}") : null; + /// + /// Determine if this resource identifier is equivalent to the given resource identifier. + /// + /// The resource identifier to compare to. + /// True if the resource identifiers are equivalent, otherwise false. + public bool Equals(ResourceIdentifier other) + { + if (other is null) + return false; + return string.Equals(this.ToString(), other.ToString(), StringComparison.InvariantCultureIgnoreCase); } /// - /// Helper method to parse a resource that comes from a provider. + /// Compre this resource identifier to the given resource identifier. /// - /// Resource ID paths consisting of name/value pairs. - private void ParseProviderResource(IList parts) + /// The resource identifier to compare to. + /// 0 if the resource identifiers are equivalent, -1 if this resource identifier + /// should be ordered before the given resource identifier, 1 if this resource identifier + /// should be ordered after the given resource identifier. + public int CompareTo(ResourceIdentifier other) { - // The resource consists of name/value pairs, make a dictionary out of it - for (var i = 0; i < parts.Count - 1; i += 2) - { - _partsDictionary[parts[i]] = parts[i + 1]; - } + if (other is null) + return 1; + return string.Compare(this.ToString(), other.ToString(), StringComparison.InvariantCultureIgnoreCase); + } - Name = parts.Last(); - parts.RemoveAt(parts.Count - 1); + /// + public override bool Equals(object obj) + { + ResourceIdentifier resourceObj = obj as ResourceIdentifier; + if (!(resourceObj is null)) + return resourceObj.Equals(this); + string stringObj = obj as string; + if (!(stringObj is null)) + return this.Equals(ResourceIdentifier.Create(stringObj)); + return false; + } - // remove the type name (there will be no typename if this is a singleton sub resource) - if (parts.Count % 2 == 1) - parts.RemoveAt(parts.Count - 1); + /// + public override int GetHashCode() + { + return ToString().GetHashCode(); + } - // If this is a top-level resource, remove the providers/Namespace pair, otherwise continue - if (parts.Count > 2 && string.Equals(parts[parts.Count - 2], KnownKeys.ProviderNamespace)) - { - parts.RemoveAt(parts.Count - 1); - parts.RemoveAt(parts.Count - 1); - } + /// + /// Convert a string into a resource identifier. + /// + /// The string representation of a resource identifier. + public static implicit operator ResourceIdentifier(string other) => (other is null ? null : ResourceIdentifier.Create(other)); - // If this is not a top-level resource, it will have a parent - Parent = parts.Count > 1 ? new ResourceIdentifier($"/{string.Join("/", parts)}") : null; - } + /// + /// Convert a resource identifier to a string + /// + /// The resource identifier. + public static implicit operator string(ResourceIdentifier id) => id?.ToString(); } } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifierExtensions.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifierExtensions.cs new file mode 100644 index 000000000000..ef5af2d1a6a7 --- /dev/null +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentifierExtensions.cs @@ -0,0 +1,160 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.ComponentModel; + +namespace Azure.ResourceManager.Core +{ + /// + /// Extensions over ResourceIdentifier types. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static class ResourceIdentifierExtensions + { + /// + /// Add a provider resource to an existing resource id. + /// + /// The id to append to. + /// The provider namespace of the added resource. + /// The simple type of the added resource, without slashes (/), + /// for example, 'virtualMachines'. + /// The name of the resource. + /// The combined resource id. + [EditorBrowsable(EditorBrowsableState.Never)] + public static TenantResourceIdentifier AppendProviderResource(this TenantResourceIdentifier identifier, string providerNamespace, string resourceType, string resourceName) + { + ValidateProviderResourceParameters(providerNamespace, resourceType, resourceName); + return new TenantResourceIdentifier(identifier, providerNamespace, resourceType, resourceName); + } + + /// + /// Add a provider resource to an existing resource id. + /// + /// The id to append to. + /// The provider namespace of the added resource. + /// The simple type of the added resource, without slashes (/), + /// for example, 'virtualMachines'. + /// The name of the resource. + /// The combined resource id. + [EditorBrowsable(EditorBrowsableState.Never)] + public static SubscriptionResourceIdentifier AppendProviderResource(this SubscriptionResourceIdentifier identifier, string providerNamespace, string resourceType, string resourceName) + { + ValidateProviderResourceParameters(providerNamespace, resourceType, resourceName); + return new SubscriptionResourceIdentifier(identifier, providerNamespace, resourceType, resourceName); + } + + /// + /// Add a provider resource to an existing resource id. + /// + /// The id to append to. + /// The provider namespace of the added resource. + /// The simple type of the added resource, without slashes (/), + /// for example, 'virtualMachines'. + /// The name of the resource. + /// The combined resource id. + [EditorBrowsable(EditorBrowsableState.Never)] + public static ResourceGroupResourceIdentifier AppendProviderResource(this ResourceGroupResourceIdentifier identifier, string providerNamespace, string resourceType, string resourceName) + { + ValidateProviderResourceParameters(providerNamespace, resourceType, resourceName); + return new ResourceGroupResourceIdentifier(identifier, providerNamespace, resourceType, resourceName); + } + + /// + /// Add a provider resource to an existing resource id. + /// + /// The id to append to. + /// The provider namespace of the added resource. + /// The simple type of the added resource, without slashes (/), + /// for example, 'virtualMachines'. + /// The name of the resource. + /// The combined resource id. + [EditorBrowsable(EditorBrowsableState.Never)] + public static LocationResourceIdentifier AppendProviderResource(this LocationResourceIdentifier identifier, string providerNamespace, string resourceType, string resourceName) + { + ValidateProviderResourceParameters(providerNamespace, resourceType, resourceName); + return new LocationResourceIdentifier(identifier, providerNamespace, resourceType, resourceName); + } + + /// + /// Add a provider resource to an existing resource id. + /// + /// The id to append to. + /// The simple type of the child resource, without slashes (/), + /// for example, 'subnets'. + /// The name of the resource. + /// The combined resource id. + [EditorBrowsable(EditorBrowsableState.Never)] + public static TenantResourceIdentifier AppendChildResource(this TenantResourceIdentifier identifier, string childResourceType, string childResourceName) + { + ValidateChildResourceParameters( childResourceType, childResourceName); + return new TenantResourceIdentifier(identifier, childResourceType, childResourceName); + } + + /// + /// Add a provider resource to an existing resource id. + /// + /// The id to append to. + /// The simple type of the child resource, without slashes (/), + /// for example, 'subnets'. + /// The name of the resource. + /// The combined resource id. + [EditorBrowsable(EditorBrowsableState.Never)] + public static SubscriptionResourceIdentifier AppendChildResource(this SubscriptionResourceIdentifier identifier, string childResourceType, string childResourceName) + { + ValidateChildResourceParameters(childResourceType, childResourceName); + return new SubscriptionResourceIdentifier(identifier, childResourceType, childResourceName); + } + + /// + /// Add a provider resource to an existing resource id. + /// + /// The id to append to. + /// The simple type of the child resource, without slashes (/), + /// for example, 'subnets'. + /// The name of the resource. + /// The combined resource id. + [EditorBrowsable(EditorBrowsableState.Never)] + public static ResourceGroupResourceIdentifier AppendChildResource(this ResourceGroupResourceIdentifier identifier, string childResourceType, string childResourceName) + { + ValidateChildResourceParameters(childResourceType, childResourceName); + return new ResourceGroupResourceIdentifier(identifier, childResourceType, childResourceName); + } + + /// + /// Add a provider resource to an existing resource id. + /// + /// The id to append to. + /// The simple type of the child resource, without slashes (/), + /// for example, 'subnets'. + /// The name of the resource. + /// The combined resource id. + [EditorBrowsable(EditorBrowsableState.Never)] + public static LocationResourceIdentifier AppendChildResource(this LocationResourceIdentifier identifier, string childResourceType, string childResourceName) + { + ValidateChildResourceParameters(childResourceType, childResourceName); + return new LocationResourceIdentifier(identifier, childResourceType, childResourceName); + } + + internal static void ValidateProviderResourceParameters(string providerNamespace, string resourceType, string resourceName) + { + ValidatePathSegment(providerNamespace, nameof(providerNamespace)); + ValidatePathSegment(resourceType, nameof(resourceType)); + ValidatePathSegment(resourceName, nameof(resourceName)); + } + + internal static void ValidateChildResourceParameters(string childResourceType, string childResourceName) + { + ValidatePathSegment(childResourceType, nameof(childResourceType)); + ValidatePathSegment(childResourceName, nameof(childResourceName)); + } + + internal static void ValidatePathSegment(string segment, string parameterName) + { + if (string.IsNullOrWhiteSpace(segment)) + throw new ArgumentNullException(parameterName); + if (segment.Contains("/")) + throw new ArgumentOutOfRangeException(parameterName, $"{parameterName} must be a single path segment"); + } + } +} diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentity.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentity.cs index ecba2a9905c8..9102f5db7b4d 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentity.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceIdentity.cs @@ -30,14 +30,14 @@ public ResourceIdentity() /// /// Dictionary with a key and a object value. /// Flag for using or not. - public ResourceIdentity(Dictionary user, bool useSystemAssigned) + public ResourceIdentity(Dictionary user, bool useSystemAssigned) { // check for combination of user and system on the impact to type value SystemAssignedIdentity = useSystemAssigned ? new SystemAssignedIdentity() : null; - UserAssignedIdentities = new Dictionary(); + UserAssignedIdentities = new Dictionary(); if (user != null) { - foreach (KeyValuePair id in user) + foreach (KeyValuePair id in user) { UserAssignedIdentities.Add(id.Key, id.Value); } @@ -49,13 +49,13 @@ public ResourceIdentity(Dictionary use /// /// The to use. /// Dictionary with a key and a object value. - public ResourceIdentity(SystemAssignedIdentity systemAssigned, IDictionary user) + public ResourceIdentity(SystemAssignedIdentity systemAssigned, IDictionary user) { // TODO: remove this constructor later SystemAssignedIdentity = systemAssigned; if (user == null) { - UserAssignedIdentities = new Dictionary(); + UserAssignedIdentities = new Dictionary(); } else { @@ -71,7 +71,7 @@ public ResourceIdentity(SystemAssignedIdentity systemAssigned, IDictionary /// Gets a dictionary of the User Assigned Identities. /// - public IDictionary UserAssignedIdentities { get; private set; } + public IDictionary UserAssignedIdentities { get; private set; } /// /// Converts a into an object. @@ -86,7 +86,7 @@ internal static ResourceIdentity Deserialize(JsonElement element) } Optional systemAssignedIdentity = default; - IDictionary userAssignedIdentities = new Dictionary(); + IDictionary userAssignedIdentities = new Dictionary(); string type = string.Empty; foreach (var property in element.EnumerateObject()) { @@ -103,7 +103,7 @@ internal static ResourceIdentity Deserialize(JsonElement element) { resourceId = keyValuePair.Name; var userAssignedIdentity = UserAssignedIdentity.Deserialize(keyValuePair.Value); - userAssignedIdentities.Add(resourceId, userAssignedIdentity); + userAssignedIdentities.Add(new ResourceGroupResourceIdentifier(resourceId), userAssignedIdentity); } continue; diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceType.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceType.cs index 62b71bc4907b..c48d43adf896 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceType.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/ResourceType.cs @@ -8,15 +8,14 @@ namespace Azure.ResourceManager.Core { /// - /// Structure representing a resource type + /// Structure representing a resource type. /// - public sealed class ResourceType : IEquatable, IEquatable, IComparable, - IComparable + public sealed class ResourceType : IEquatable, IComparable { /// - /// The "none" resource type + /// The resource type for the root of the resource hierarchy. /// - public static readonly ResourceType None = new ResourceType { Namespace = string.Empty, Type = string.Empty }; + public static ResourceType RootResourceType => new ResourceType(string.Empty, string.Empty); /// /// Initializes a new instance of the class. @@ -28,6 +27,29 @@ public ResourceType(string resourceIdOrType) throw new ArgumentException($"{nameof(resourceIdOrType)} cannot be null or whitespace", nameof(resourceIdOrType)); Parse(resourceIdOrType); + Types = Type.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + } + + /// + /// Create a resource type given the namespace and typename components. + /// + /// + /// + internal ResourceType(string providerNamespace, string name) + { + Namespace = providerNamespace; + Type = name; + Types = Type.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + } + + /// + /// Create child resource type using parent resource type + /// + /// + /// + internal ResourceType(ResourceType parent, string childType) + : this(parent.Namespace, $"{parent.Type}/{childType}") + { } private ResourceType() @@ -44,23 +66,28 @@ private ResourceType() /// public string Type { get; private set; } + internal IList Types { get; } = new List(); + /// - /// Gets the resource type Parent. + /// Determines if this resource type is the parent of the given resource. /// - public ResourceType Parent + /// + /// + public bool IsParentOf(ResourceType child) { - get + if (!string.Equals(Namespace, child.Namespace, StringComparison.InvariantCultureIgnoreCase)) + return false; + var types = Type.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + var childTypes = child.Type.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + if (types.Length >= childTypes.Length) + return false; + for (int i = 0; i < types.Length; ++i) { - var parts = Type.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - - if (parts.Length < 2) - return None; - - var list = new List(parts); - list.RemoveAt(list.Count - 1); - - return new ResourceType($"{Namespace}/{string.Join("/", list.ToArray())}"); + if (!string.Equals(types[i], childTypes[i], StringComparison.InvariantCultureIgnoreCase)) + return false; } + + return true; } /// @@ -75,46 +102,6 @@ public static implicit operator ResourceType(string other) return new ResourceType(other); } - /// - /// Implicit operator for initializing a string instance from a ResourceType. - /// - /// to be converted into a string object. - public static implicit operator string(ResourceType other) - { - if (other is null) - return null; - - return other.ToString(); - } - - /// - /// Compares a object with a . - /// - /// object. - /// String. - /// True if they are equal, otherwise False. - public static bool operator ==(ResourceType source, string target) - { - if (source is null) - return target is null; - - return source.Equals(target); - } - - /// - /// Compares a with a object. - /// - /// String representation of a ResourceType. - /// object. - /// True if they are equal, otherwise False. - public static bool operator ==(string source, ResourceType target) - { - if (target is null) - return source is null; - - return target.Equals(source); - } - /// /// Compares two objects. /// @@ -129,34 +116,6 @@ public static implicit operator string(ResourceType other) return source.Equals(target); } - /// - /// Compares a object with a . - /// - /// object. - /// String representation of a ResourceType. - /// False if they are equal, otherwise True. - public static bool operator !=(ResourceType source, string target) - { - if (source is null) - return !(target is null); - - return !source.Equals(target); - } - - /// - /// Compares a with a object. - /// - /// String. - /// object. - /// False if they are equal, otherwise True. - public static bool operator !=(string source, ResourceType target) - { - if (target is null) - return !(source is null); - - return !target.Equals(source); - } - /// /// Compares two objects. /// @@ -184,30 +143,15 @@ public int CompareTo(ResourceType other) if (ReferenceEquals(this, other)) return 0; - int compareResult = 0; - if ((compareResult = string.Compare(Namespace, other.Namespace, StringComparison.InvariantCultureIgnoreCase)) == 0 && - (compareResult = string.Compare(Type, other.Type, StringComparison.InvariantCultureIgnoreCase)) == 0 && - (!(other.Parent is null))) + int compareResult = string.Compare(Namespace, other.Namespace, StringComparison.InvariantCultureIgnoreCase); + if (compareResult == 0) { - return Parent.CompareTo(other.Parent); + compareResult = string.Compare(Type, other.Type, StringComparison.InvariantCultureIgnoreCase); } - + return compareResult; } - /// - /// Compares this with a resource type representation as a string. - /// - /// String to compare. - /// -1 for less than, 0 for equals, 1 for greater than. - public int CompareTo(string other) - { - if (other is null) - return 1; - - return CompareTo(new ResourceType(other)); - } - /// /// Compares this instance with another object and determines if they are equals. /// @@ -221,19 +165,6 @@ public bool Equals(ResourceType other) return string.Equals(ToString(), other.ToString(), StringComparison.InvariantCultureIgnoreCase); } - /// - /// Compares this instance with a string and determines if they are equals. - /// - /// String to compare. - /// True if they are equals, otherwise false. - public bool Equals(string other) - { - if (other is null) - return false; - - return string.Equals(ToString(), other, StringComparison.InvariantCultureIgnoreCase); - } - /// public override string ToString() { diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/RootResourceIdentifier.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/RootResourceIdentifier.cs new file mode 100644 index 000000000000..1d5d412c6a88 --- /dev/null +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/RootResourceIdentifier.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Azure.ResourceManager.Core +{ + /// + /// A resource Id representing the root of the resource hierarchy. + /// + public sealed class RootResourceIdentifier : ResourceIdentifier + { + internal RootResourceIdentifier() + : base(ResourceType.RootResourceType, string.Empty) + { + } + + internal override string ToResourceString() + { + return string.Empty; + } + + /// + public override bool TryGetParent(out ResourceIdentifier containerId) + { + containerId = default(ResourceIdentifier); + return false; + } + } +} diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/SubscriptionResourceIdentifier.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/SubscriptionResourceIdentifier.cs new file mode 100644 index 000000000000..9ea234562109 --- /dev/null +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/SubscriptionResourceIdentifier.cs @@ -0,0 +1,125 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; + +namespace Azure.ResourceManager.Core +{ + /// + /// The identifier of a resource that is contained in a subscription. + /// + public class SubscriptionResourceIdentifier : TenantResourceIdentifier + { + /// + /// Internal use only. + /// + internal SubscriptionResourceIdentifier() + { + } + + /// + /// Internal use only. + /// + /// The subscription GUID. + internal SubscriptionResourceIdentifier(Guid id) + { + Name = id.ToString(); + ResourceType = ResourceIdentifier.SubscriptionType; + Parent = ResourceIdentifier.RootResourceIdentifier; + IsChild = false; + SubscriptionId = Name; + } + + /// + /// Initializes a new instance of the class + /// for resources in the sanem namespace as their parent resource. + /// + /// The resource id of the parent resource. + /// The simple type of this resource, for example 'subnets'. + /// The name of this resource. + /// The resource identifier for the given child resource. + internal SubscriptionResourceIdentifier(SubscriptionResourceIdentifier parent, string childResourceType, string childResourceName) + : base(parent, childResourceType, childResourceName) + { + SubscriptionId = parent.SubscriptionId; + } + + /// + /// Initializes a new instance of the class + /// for resources in a different namespace than their parent resource. + /// + /// The resource id of the parent resource. + /// The namespace of this resource, for example 'Microsoft.Compute'. + /// The simple tyoe of this resource, with no slashes. For example, 'virtualMachines'. + /// Thge name of this resource. + /// The resource identifier for the given resource. + internal SubscriptionResourceIdentifier(SubscriptionResourceIdentifier parent, string providerNamespace, string resourceType, string resourceName) + : base(parent, providerNamespace, resourceType, resourceName) + { + SubscriptionId = parent.SubscriptionId; + } + + /// + /// Initializes a new instance of the class. + /// + /// The string representation of the subscription id. This can be in the form of a GUID, + /// or a full resource id like '/subscriptions/xxxxx-yyyy-zzzz-wwwwww'. + public SubscriptionResourceIdentifier(string resourceIdOrSubscriptionId) + { + Guid subscriptionGuid; + if (Guid.TryParse(resourceIdOrSubscriptionId, out subscriptionGuid)) + { + Name = resourceIdOrSubscriptionId; + ResourceType = ResourceIdentifier.SubscriptionType; + Parent = ResourceIdentifier.RootResourceIdentifier; + IsChild = false; + SubscriptionId = resourceIdOrSubscriptionId; + } + else + { + ResourceIdentifier rawId = ResourceIdentifier.Create(resourceIdOrSubscriptionId); + SubscriptionResourceIdentifier id = rawId as SubscriptionResourceIdentifier; + if (id is null || rawId.TryGetLocation(out _) || rawId.TryGetResourceGroupName(out _)) + throw new ArgumentException("Not a valid subscription level resource", nameof(resourceIdOrSubscriptionId)); + Name = id.Name; + ResourceType = id.ResourceType; + Parent = id.Parent; + IsChild = id.IsChild; + SubscriptionId = id.SubscriptionId; + } + } + + /// + /// The subscription id (Guid) for this resource. + /// + public string SubscriptionId { get; internal set; } + + /// + public override bool TryGetSubscriptionId(out string subscriptionId) + { + subscriptionId = SubscriptionId; + return true; + } + + /// + /// Convert a string resource id into a subscription resource identifier. + /// + /// The string representation of a resource identifier. + public static implicit operator SubscriptionResourceIdentifier(string other) + { + if (other is null) + return null; + SubscriptionResourceIdentifier id = ResourceIdentifier.Create(other) as SubscriptionResourceIdentifier; + if (id is null) + throw new ArgumentException("Not a valid subscription level resource", nameof(other)); + return id; + } + + internal override string ToResourceString() + { + if (Parent is RootResourceIdentifier) + return $"/subscriptions/{SubscriptionId}"; + return base.ToResourceString(); + } + } +} diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TenantResourceIdentifier.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TenantResourceIdentifier.cs new file mode 100644 index 000000000000..0743da2cf2d5 --- /dev/null +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TenantResourceIdentifier.cs @@ -0,0 +1,86 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Linq; + +namespace Azure.ResourceManager.Core +{ + /// + /// The identifier of any resource + /// + public class TenantResourceIdentifier : ResourceIdentifier + { + internal TenantResourceIdentifier() + { + } + + /// + /// Initializes a new instance of the class + /// + /// The resource type (including namespace and type). + /// The name of the resource. + internal TenantResourceIdentifier(ResourceType resourceType, string name) : base(resourceType, name) + { + Parent = ResourceIdentifier.RootResourceIdentifier; + } + + /// + /// Initializes a new instance of the class + /// for resources in the same namespace as their parent. + /// + /// The parent resource id. + /// The simple type name of the resource without slashes (/), for example 'virtualMachines'. + /// The name of the resource. + internal TenantResourceIdentifier(TenantResourceIdentifier parent, string typeName, string resourceName) + : base(new ResourceType(parent.ResourceType, typeName), resourceName) + { + Parent = parent; + IsChild = true; + } + + /// + /// Initializes a new instance of the class + /// for resources in a different namespace than their parent. + /// + /// The parent resource id. + /// The namespace of the resource type, for example, 'Microsoft.Compute'. + /// The simple type name of the resource, without slashes (/). For example, 'virtualMachines'. + /// The name of the resource. + internal TenantResourceIdentifier(TenantResourceIdentifier parent, string providerNamespace, string typeName, string resourceName) + : base(new ResourceType(providerNamespace, typeName), resourceName) + { + Parent = parent; + } + + /// + /// Initializes a new instance of the class. + /// + /// The string representation of a resource identifier. + public TenantResourceIdentifier(string resourceId) + { + var rawId = ResourceIdentifier.Create(resourceId); + TenantResourceIdentifier id = rawId as TenantResourceIdentifier; + if (id is null || rawId.TryGetSubscriptionId(out _)) + throw new ArgumentException("Not a valid tenant level resource", nameof(resourceId)); + Name = id.Name; + ResourceType = id.ResourceType; + Parent = id.Parent; + IsChild = id.IsChild; + } + + /// + /// Convert a string resource identifier into a TenantResourceIdentifier. + /// + /// The string representation of a subscription resource identifier. + public static implicit operator TenantResourceIdentifier(string other) + { + if (other is null) + return null; + TenantResourceIdentifier id = ResourceIdentifier.Create(other) as TenantResourceIdentifier; + if (id is null) + throw new ArgumentException("Not a valid tenant level resource", nameof(other)); + return id; + } + } +} diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TrackedResource.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TrackedResource.cs index a8639060c3bf..af6de769670b 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TrackedResource.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Resources/TrackedResource.cs @@ -10,7 +10,7 @@ namespace Azure.ResourceManager.Core /// Generic representation of a tracked resource. All tracked resources should extend this class /// [ReferenceType] - public abstract class TrackedResource : Resource + public abstract class TrackedResource : Resource where TIdentifier : TenantResourceIdentifier { /// /// Gets the tags. @@ -26,6 +26,6 @@ public abstract class TrackedResource : Resource /// /// Gets or sets the identifier for the resource. /// - public override ResourceIdentifier Id { get; protected set; } + public override TIdentifier Id { get; protected set; } } } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionContainer.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionContainer.cs index 388fdfa3a4a8..161526d14919 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionContainer.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionContainer.cs @@ -12,7 +12,7 @@ namespace Azure.ResourceManager.Core /// /// A class representing collection of Subscription and their operations /// - public class SubscriptionContainer : ContainerBase + public class SubscriptionContainer : ContainerBase { /// /// Initializes a new instance of the class. @@ -79,8 +79,8 @@ protected override void Validate(ResourceIdentifier identifier) /// Get an instance of the operations this container holds. /// /// The guid of the subscription to be found. - /// An instance of . - protected override ResourceOperationsBase GetOperation(string subscriptionGuid) + /// An instance of . + protected override ResourceOperationsBase GetOperation(string subscriptionGuid) { return new SubscriptionOperations(ClientOptions, subscriptionGuid, Credential, BaseUri); } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionOperations.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionOperations.cs index e9dd7bfb220d..bfba8c412628 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionOperations.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/SubscriptionOperations.cs @@ -12,7 +12,7 @@ namespace Azure.ResourceManager.Core /// /// A class representing the operations that can be performed over a specific subscription. /// - public class SubscriptionOperations : ResourceOperationsBase + public class SubscriptionOperations : ResourceOperationsBase { /// /// The resource type for subscription @@ -34,7 +34,7 @@ protected SubscriptionOperations() /// A credential used to authenticate to an Azure Service. /// The base URI of the service. internal SubscriptionOperations(AzureResourceManagerClientOptions options, string subscriptionId, TokenCredential credential, Uri baseUri) - : base(options, $"/subscriptions/{subscriptionId}", credential, baseUri) + : base(options, new SubscriptionResourceIdentifier(subscriptionId), credential, baseUri) { } @@ -43,7 +43,7 @@ internal SubscriptionOperations(AzureResourceManagerClientOptions options, strin /// /// The subscription operations to copy client options from. /// The identifier of the subscription. - protected SubscriptionOperations(SubscriptionOperations subscription, ResourceIdentifier id) + protected SubscriptionOperations(SubscriptionOperations subscription, SubscriptionResourceIdentifier id) : base(subscription.ClientOptions, id, subscription.Credential, subscription.BaseUri) { } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/TenantOperations.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/TenantOperations.cs index 556ef04683bf..fa108fa44a13 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/src/TenantOperations.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/TenantOperations.cs @@ -18,7 +18,7 @@ public class TenantOperations : OperationsBase /// /// The resource type for subscription /// - public static readonly ResourceType ResourceType = "/tenants"; // placeholder pending on the outcome of ADO #5199 + public static readonly ResourceType ResourceType = ResourceType.RootResourceType; /// /// Initializes a new instance of the class. @@ -27,7 +27,7 @@ public class TenantOperations : OperationsBase /// A credential used to authenticate to an Azure Service. /// The base URI of the service. internal TenantOperations(AzureResourceManagerClientOptions options, TokenCredential credential, Uri baseUri) - : base(options, "/tenants", credential, baseUri) + : base(options, ResourceIdentifier.RootResourceIdentifier, credential, baseUri) { } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/src/Utils/ListExtensions.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Utils/ListExtensions.cs new file mode 100644 index 000000000000..83a474b67d38 --- /dev/null +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/src/Utils/ListExtensions.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Azure.ResourceManager.Core +{ + internal static class ListExtensions + { + /// + /// Trims the first n elements from a list, and returns the altered list. + /// + /// The type of element in the list. + /// The list to trim. + /// The number of elements to remove from the front of the list. + /// The altered input list. + internal static List Trim(this List list, int numberToTrim) + { + if (list is null) + throw new ArgumentNullException(nameof(list)); + if (numberToTrim < 0 || numberToTrim > list.Count) + throw new ArgumentOutOfRangeException(nameof(numberToTrim)); + list.RemoveRange(0, numberToTrim); + return list; + } + } +} diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/GenericResourceTests.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/GenericResourceTests.cs index 7da80a8261b1..73bfcbdfb4e5 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/GenericResourceTests.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/GenericResourceTests.cs @@ -75,9 +75,9 @@ public async Task GetGenericsBadNameSpace() [RecordedTest] public async Task GetGenericsBadApiVersion() { - ResourceIdentifier rgid = $"/subscriptions/{TestEnvironment.SubscriptionId}/resourceGroups/{_rgName}"; + ResourceGroupResourceIdentifier rgid = $"/subscriptions/{TestEnvironment.SubscriptionId}/resourceGroups/{_rgName}"; AzureResourceManagerClientOptions options = new AzureResourceManagerClientOptions(); - options.ApiVersions.SetApiVersion(rgid.Type, "1500-10-10"); + options.ApiVersions.SetApiVersion(rgid.ResourceType, "1500-10-10"); var client = GetArmClient(options); var subOp = client.GetSubscriptionOperations(TestEnvironment.SubscriptionId); var genericResourceOperations = new GenericResourceOperations(subOp, rgid); @@ -96,7 +96,7 @@ public async Task GetGenericsBadApiVersion() [RecordedTest] public async Task GetGenericsGoodApiVersion() { - ResourceIdentifier rgid = $"/subscriptions/{TestEnvironment.SubscriptionId}/resourceGroups/{_rgName}"; + ResourceGroupResourceIdentifier rgid = $"/subscriptions/{TestEnvironment.SubscriptionId}/resourceGroups/{_rgName}"; AzureResourceManagerClientOptions options = new AzureResourceManagerClientOptions(); var client = GetArmClient(options); var subOp = client.GetSubscriptionOperations(TestEnvironment.SubscriptionId); diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/ResourceGroupOperationsTests.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/ResourceGroupOperationsTests.cs index ab93a2e95525..db593a539454 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/ResourceGroupOperationsTests.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/ResourceGroupOperationsTests.cs @@ -10,7 +10,7 @@ namespace Azure.ResourceManager.Core.Tests public class ResourceGroupOperationsTests : ResourceManagerTestBase { public ResourceGroupOperationsTests(bool isAsync) - : base(isAsync)//, RecordedTestMode.Record) + : base(isAsync) //, RecordedTestMode.Record) { } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/SubscriptionOperationsTests.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/SubscriptionOperationsTests.cs index 0a22285167d9..aed0fd78d91c 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/SubscriptionOperationsTests.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Scenario/SubscriptionOperationsTests.cs @@ -21,7 +21,7 @@ public SubscriptionOperationsTests(bool isAsync) public void GetSubscriptionOperation() { var sub = Client.GetSubscriptionOperations(TestEnvironment.SubscriptionId); - Assert.AreEqual(sub.Id.Subscription, TestEnvironment.SubscriptionId); + Assert.AreEqual(sub.Id.SubscriptionId, TestEnvironment.SubscriptionId); } [TestCase(null)] diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/IdentityTests.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/IdentityTests.cs index 7974378fe618..a725b9130f75 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/IdentityTests.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/IdentityTests.cs @@ -27,7 +27,7 @@ public void CheckNoParamConstructor() [TestCase (null, true)] public void CheckUserTrueConstructor(string resourceID, bool invalidParameter) { - var dict1 = new Dictionary(); + var dict1 = new Dictionary(); if (invalidParameter) { @@ -55,7 +55,7 @@ public void CheckUserTrueConstructor(string resourceID, bool invalidParameter) [TestCase(null, true)] public void CheckUserFalseConstructor(string resourceID, bool invalidParameter) { - var dict1 = new Dictionary(); + var dict1 = new Dictionary(); if(invalidParameter) { @@ -97,8 +97,8 @@ public void EqualsNullOtherTest() [TestCase] public void EqualsReferenceTestTrue() { - var dict1 = new Dictionary(); - dict1["/subscriptions/6b085460-5vbg-477e-ba44-1035046e9101/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty); + var dict1 = new Dictionary(); + dict1["/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty); var system = new SystemAssignedIdentity(Guid.Empty, Guid.Empty); ResourceIdentity identity = new ResourceIdentity(system, dict1); ResourceIdentity identity1 = identity; @@ -108,12 +108,12 @@ public void EqualsReferenceTestTrue() [TestCase] public void EqualsTestTrue() { - var dict1 = new Dictionary(); - dict1["/subscriptions/6b085460-5f21-477e-ba44-1035046e9000/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty); + var dict1 = new Dictionary(); + dict1["/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty); var system = new SystemAssignedIdentity(Guid.Empty, Guid.Empty); ResourceIdentity identity = new ResourceIdentity(system, dict1); - var dict2 = new Dictionary(); - dict2["/subscriptions/6b085460-5f21-477e-ba44-1035046e9000/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty); + var dict2 = new Dictionary(); + dict2["/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty); var system2 = new SystemAssignedIdentity(Guid.Empty, Guid.Empty); ResourceIdentity identity1 = new ResourceIdentity(system2, dict2); Assert.IsTrue(identity.Equals(identity1)); @@ -122,12 +122,12 @@ public void EqualsTestTrue() [TestCase] public void EqualsTestFalse() { - var dict1 = new Dictionary(); - dict1["/subscriptions/6b085460-5f21-477e-ba44-1035nbhs9101/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty); + var dict1 = new Dictionary(); + dict1["/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty); var system = new SystemAssignedIdentity(Guid.Empty, Guid.Empty); ResourceIdentity identity = new ResourceIdentity(system, dict1); - var dict2 = new Dictionary(); - dict2["/subscriptions/6b08dfsg-5f21-475e-ba44-1035046e9101/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty); + var dict2 = new Dictionary(); + dict2["/subscriptions/d96407f5-db8f-4325-b582-84ad21310bd8/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty); var system2 = new SystemAssignedIdentity(Guid.Empty, Guid.Empty); ResourceIdentity identity1 = new ResourceIdentity(system2, dict2); Assert.IsFalse(identity.Equals(identity1)); @@ -136,12 +136,12 @@ public void EqualsTestFalse() [TestCase] public void EqualsTestFalseSameKey() { - var dict1 = new Dictionary(); - dict1["/subscriptions/6b085460-5f21-477e-ba44-10ancd6e9101/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty); + var dict1 = new Dictionary(); + dict1["/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(Guid.Empty, Guid.Empty); var system = new SystemAssignedIdentity(Guid.Empty, Guid.Empty); ResourceIdentity identity = new ResourceIdentity(system, dict1); - var dict2 = new Dictionary(); - dict2["/subscriptions/6b085460-5f21-477e-ba44-10ancd6e9101/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), Guid.Empty); + var dict2 = new Dictionary(); + dict2["/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.Web/sites/autotest"] = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), Guid.Empty); var system2 = new SystemAssignedIdentity(Guid.Empty, Guid.Empty); ResourceIdentity identity1 = new ResourceIdentity(system2, dict2); Assert.IsFalse(identity.Equals(identity1)); @@ -188,7 +188,7 @@ public void TestDeserializerInvalidType() var identityJsonProperty = DeserializerHelper("InvalidType.json"); ResourceIdentity back = ResourceIdentity.Deserialize(identityJsonProperty.Value); var user = back.UserAssignedIdentities; - Assert.AreEqual("/subscriptions/db1ab6f0-4769-tgds-930e-01e2ef9c123c/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity", user.Keys.First().ToString()); + Assert.AreEqual("/subscriptions/d96407f5-db8f-4325-b582-84ad21310bd8/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity", user.Keys.First().ToString()); Assert.AreEqual("9a2eaa6a-b49c-4a63-afb5-3b72e3e65422", user.Values.First().ClientId.ToString()); Assert.AreEqual("77563a98-c9d9-4f7b-a7af-592d21fa2153", user.Values.First().PrincipalId.ToString()); } @@ -243,10 +243,10 @@ public void TestDeserializerValidSystemAndMultUser() Assert.IsTrue("22fddec1-8b9f-49dc-bd72-ddaf8f215570".Equals(back.SystemAssignedIdentity.PrincipalId.ToString())); Assert.IsTrue("72f988bf-86f1-41af-91ab-2d7cd011db40".Equals(back.SystemAssignedIdentity.TenantId.ToString())); var user = back.UserAssignedIdentities; - Assert.AreEqual("/subscriptions/db1ab6f0-4769-4b27-930e-01e2ef9c123z/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity0", user.Keys.First().ToString()); + Assert.AreEqual("/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity0", user.Keys.First().ToString()); Assert.AreEqual("9a2eaa6a-b49c-4c63-afb5-3b72e3e65422", user.Values.First().ClientId.ToString()); Assert.AreEqual("77563a98-c9d9-477b-a7af-592d21fa2153", user.Values.First().PrincipalId.ToString()); - Assert.AreEqual("/subscriptions/db1ab6f0-4769-4b27-930e-01e2ef9cfrgh/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity1", user.Keys.ElementAt(1).ToString()); + Assert.AreEqual("/subscriptions/d96407f5-db8f-4325-b582-84ad21310bd8/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity1", user.Keys.ElementAt(1).ToString()); Assert.AreEqual("9a2eaa6a-b49c-4c63-afb5-3b72e3c65420", user.Values.ElementAt(1).ClientId.ToString()); Assert.AreEqual("77563a98-c9d9-477b-a7af-592d2bfa2150", user.Values.ElementAt(1).PrincipalId.ToString()); } @@ -278,7 +278,7 @@ public void TestSerializerValidSystemAndUser() { SystemAssignedIdentity systemAssignedIdentity = new SystemAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), new Guid("de29bab1-49e1-4705-819b-4dfddceaaa98")); UserAssignedIdentity userAssignedIdentity = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), new Guid("de29bab1-49e1-4705-819b-4dfddceaaa98")); - var dict1 = new Dictionary(); + var dict1 = new Dictionary(); dict1["/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test/providers/Microsoft.Web/sites/autoreport"] = userAssignedIdentity; ResourceIdentity identity = new ResourceIdentity(systemAssignedIdentity, dict1); string system = "\"principalId\":\"de29bab1-49e1-4705-819b-4dfddceaaa98\",\"tenantId\":\"72f988bf-86f1-41af-91ab-2d7cd011db47\""; @@ -309,7 +309,7 @@ public void TestSerializerValidSystemAndMultUser() SystemAssignedIdentity systemAssignedIdentity = new SystemAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), new Guid("de29bab1-49e1-4705-819b-4dfddceaaa98")); UserAssignedIdentity userAssignedIdentity1 = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), new Guid("de29bab1-49e1-4705-819b-4dfddceaaa98")); UserAssignedIdentity userAssignedIdentity2 = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011cb47"), new Guid("de29bab1-49e1-4705-819b-4dfddcebaa98")); - var dict1 = new Dictionary(); + var dict1 = new Dictionary(); dict1["/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test/providers/Microsoft.Web/sites/autoreport1"] = userAssignedIdentity1; dict1["/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test/providers/Microsoft.Web/sites/autoreport2"] = userAssignedIdentity2; ResourceIdentity identity = new ResourceIdentity(systemAssignedIdentity, dict1); @@ -365,7 +365,7 @@ public void TestSerializerValidSystemOnly() public void TestSerializerValidUserEmptySystem() { UserAssignedIdentity userAssignedIdentity = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), new Guid("de29bab1-49e1-4705-819b-4dfddceaaa98")); - var dict1 = new Dictionary(); + var dict1 = new Dictionary(); dict1["/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test/providers/Microsoft.Web/sites/autoreport"] = userAssignedIdentity; ResourceIdentity identity = new ResourceIdentity(dict1, true); string system = "\"principalId\":\"null\",\"tenantId\":\"null\""; @@ -394,7 +394,7 @@ public void TestSerializerValidUserEmptySystem() public void TestSerializerValidUserNullSystem() { UserAssignedIdentity userAssignedIdentity = new UserAssignedIdentity(new Guid("72f988bf-86f1-41af-91ab-2d7cd011db47"), new Guid("de29bab1-49e1-4705-819b-4dfddceaaa98")); - var dict1 = new Dictionary(); + var dict1 = new Dictionary(); dict1["/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test/providers/Microsoft.Web/sites/autoreport"] = userAssignedIdentity; ResourceIdentity identity = new ResourceIdentity(dict1, false); string user = "{\"clientId\":\"72f988bf-86f1-41af-91ab-2d7cd011db47\",\"principalId\":\"de29bab1-49e1-4705-819b-4dfddceaaa98\"}"; diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/Resource/TestResource.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/Resource/TestResource.cs index 8bb221bae37e..84393ffb3bbb 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/Resource/TestResource.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/Resource/TestResource.cs @@ -4,13 +4,13 @@ namespace Azure.ResourceManager.Core.Tests { - public class TestResource : Resource + public class TestResource : Resource where TIdentifier : TenantResourceIdentifier { public TestResource(string id) { - Id = id; + Id = ResourceIdentifier.Create(id) as TIdentifier; } - public override ResourceIdentifier Id { get; protected set; } + public override TIdentifier Id { get; protected set; } } } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceIdentifierTests.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceIdentifierTests.cs index abb6af7b7757..ab392e77bb3a 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceIdentifierTests.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceIdentifierTests.cs @@ -24,8 +24,8 @@ public void Setup() public void CanParseTenant(string id) { ResourceIdentifier asIdentifier = id; - Assert.AreEqual(asIdentifier.Type.Namespace, "Microsoft.Billing"); - Assert.AreEqual(asIdentifier.Type.Type, "billingAccounts"); + Assert.AreEqual(asIdentifier.ResourceType.Namespace, "Microsoft.Billing"); + Assert.AreEqual(asIdentifier.ResourceType.Type, "billingAccounts"); Assert.AreEqual(asIdentifier.Name, "3984c6f4-2d2a-4b04-93ce-43cf4824b698%3Ae2f1492a-a492-468d-909f-bf7fe6662c01_2019-05-31"); } @@ -49,7 +49,7 @@ public void InvalidTenantID(string id) public void InvalidRPIds(string invalidID) { Assert.Throws(() => { ResourceIdentifier subject = invalidID; }); - Assert.Throws(() => { ResourceIdentifier subject = new ResourceIdentifier(invalidID); }); + Assert.Throws(() => { ResourceIdentifier subject = ResourceIdentifier.Create(invalidID); }); } [TestCase (null)] @@ -88,11 +88,11 @@ public void PublicConstructor(string resourceProviderID) { if (resourceProviderID is null) { - Assert.Throws(() => { ResourceIdentifier myResource = new ResourceIdentifier(resourceProviderID); }); + Assert.Throws(() => { ResourceIdentifier myResource = ResourceIdentifier.Create(resourceProviderID); }); } else { - ResourceIdentifier myResource = new ResourceIdentifier(resourceProviderID); + ResourceIdentifier myResource = ResourceIdentifier.Create(resourceProviderID); Assert.AreEqual(myResource.ToString(), resourceProviderID); } } @@ -103,12 +103,12 @@ public void PublicConstructor(string resourceProviderID) public void CanParseRPIds(string subscription, string resourceGroup, string provider, string type, string name) { var resourceId = $"/subscriptions/{subscription}/resourceGroups/{Uri.EscapeDataString(resourceGroup)}/providers/{provider}/{type}/{Uri.EscapeDataString(name)}"; - ResourceIdentifier subject = resourceId; + ResourceGroupResourceIdentifier subject = resourceId; Assert.AreEqual(subject.ToString(), resourceId); - Assert.AreEqual(subject.Subscription, subscription); - Assert.AreEqual(Uri.UnescapeDataString(subject.ResourceGroup), resourceGroup); - Assert.AreEqual(subject.Type.Namespace, provider); - Assert.AreEqual(subject.Type.Type, type); + Assert.AreEqual(subject.SubscriptionId, subscription); + Assert.AreEqual(Uri.UnescapeDataString(subject.ResourceGroupName), resourceGroup); + Assert.AreEqual(subject.ResourceType.Namespace, provider); + Assert.AreEqual(subject.ResourceType.Type, type); Assert.AreEqual(Uri.UnescapeDataString(subject.Name), name); } @@ -122,8 +122,8 @@ public void CanParseExtensionResourceIds(string baseId, string extensionNamespac ResourceIdentifier targetResourceId = baseId; ResourceIdentifier subject = $"{baseId}/providers/{extensionNamespace}/{extensionType}/{extensionName}"; ResourceType expectedType = $"{extensionNamespace}/{extensionType}"; - Assert.AreNotEqual(targetResourceId.Type, subject.Type); - Assert.AreEqual(expectedType, subject.Type); + Assert.AreNotEqual(targetResourceId.ResourceType, subject.ResourceType); + Assert.AreEqual(expectedType, subject.ResourceType); Assert.NotNull(subject.Parent); Assert.AreEqual(targetResourceId, subject.Parent); } @@ -132,32 +132,32 @@ public void CanParseExtensionResourceIds(string baseId, string extensionNamespac public void CanParseProxyResource(string subscription, string rg, string resourceNamespace, string resource, string type) { string id = $"/subscriptions/{subscription}/resourceGroups/{rg}/providers/{resourceNamespace}/{resource}"; - ResourceIdentifier subject = id; + ResourceGroupResourceIdentifier subject = id; Assert.AreEqual(subject.ToString(), id); - Assert.AreEqual(subject.Subscription, subscription); - Assert.AreEqual(subject.Type.Namespace, resourceNamespace); - Assert.AreEqual(subject.Type.Type, type); + Assert.AreEqual(subject.SubscriptionId, subscription); + Assert.AreEqual(subject.ResourceType.Namespace, resourceNamespace); + Assert.AreEqual(subject.ResourceType.Type, type); } [Test] public void CanParseSubscriptions() { - ResourceIdentifier subject = "/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575"; + SubscriptionResourceIdentifier subject = "/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575"; Assert.AreEqual(subject.ToString(), "/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575"); - Assert.AreEqual(subject.Subscription, "0c2f6471-1bf0-4dda-aec3-cb9272f09575"); - Assert.AreEqual(subject.Type.Namespace, "Microsoft.Resources"); - Assert.AreEqual(subject.Type.Type, "subscriptions"); + Assert.AreEqual(subject.SubscriptionId, "0c2f6471-1bf0-4dda-aec3-cb9272f09575"); + Assert.AreEqual(subject.ResourceType.Namespace, "Microsoft.Resources"); + Assert.AreEqual(subject.ResourceType.Type, "subscriptions"); } [Test] public void CanParseResourceGroups() { - ResourceIdentifier subject = "/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575/resourceGroups/myRg"; + ResourceGroupResourceIdentifier subject = "/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575/resourceGroups/myRg"; Assert.AreEqual(subject.ToString(), "/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575/resourceGroups/myRg"); - Assert.AreEqual(subject.Subscription, "0c2f6471-1bf0-4dda-aec3-cb9272f09575"); - Assert.AreEqual(subject.ResourceGroup, "myRg"); - Assert.AreEqual(subject.Type.Namespace, "Microsoft.Resources"); - Assert.AreEqual(subject.Type.Type, "resourceGroups"); + Assert.AreEqual(subject.SubscriptionId, "0c2f6471-1bf0-4dda-aec3-cb9272f09575"); + Assert.AreEqual(subject.ResourceGroupName, "myRg"); + Assert.AreEqual(subject.ResourceType.Namespace, "Microsoft.Resources"); + Assert.AreEqual(subject.ResourceType.Type, "subscriptions/resourceGroups"); } [TestCase("MyVnet", "MySubnet")] @@ -166,34 +166,75 @@ public void CanParseResourceGroups() public void CanParseChildResources(string parentName, string name) { var resourceId = $"/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575/resourceGroups/myRg/providers/Microsoft.Network/virtualNetworks/{Uri.EscapeDataString(parentName)}/subnets/{Uri.EscapeDataString(name)}"; - ResourceIdentifier subject = resourceId; + ResourceGroupResourceIdentifier subject = resourceId; Assert.AreEqual(subject.ToString(), resourceId); - Assert.AreEqual(subject.Subscription, "0c2f6471-1bf0-4dda-aec3-cb9272f09575"); - Assert.AreEqual(Uri.UnescapeDataString(subject.ResourceGroup), "myRg"); - Assert.AreEqual(subject.Type.Namespace, "Microsoft.Network"); - Assert.AreEqual(subject.Type.Parent.Type, "virtualNetworks"); - Assert.AreEqual(subject.Type.Type, "virtualNetworks/subnets"); + Assert.AreEqual(subject.SubscriptionId, "0c2f6471-1bf0-4dda-aec3-cb9272f09575"); + Assert.AreEqual(Uri.UnescapeDataString(subject.ResourceGroupName), "myRg"); + Assert.AreEqual(subject.ResourceType.Namespace, "Microsoft.Network"); + Assert.AreEqual(subject.Parent.ResourceType.Type, "virtualNetworks"); + Assert.AreEqual(subject.ResourceType.Type, "virtualNetworks/subnets"); Assert.AreEqual(Uri.UnescapeDataString(subject.Name), name); // check parent type parsing - var parentResource = $"/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575/resourceGroups/myRg/providers/Microsoft.Network/virtualNetworks/{Uri.EscapeDataString(parentName)}"; + ResourceGroupResourceIdentifier parentResource = $"/subscriptions/0c2f6471-1bf0-4dda-aec3-cb9272f09575/resourceGroups/myRg/providers/Microsoft.Network/virtualNetworks/{Uri.EscapeDataString(parentName)}"; Assert.AreEqual(subject.Parent, parentResource); - Assert.AreEqual(subject.Parent.ToString(), parentResource); - Assert.AreEqual(subject.Parent.Subscription, "0c2f6471-1bf0-4dda-aec3-cb9272f09575"); - Assert.AreEqual(Uri.UnescapeDataString(subject.Parent.ResourceGroup), "myRg"); - Assert.AreEqual(subject.Parent.Type.Namespace, "Microsoft.Network"); - Assert.AreEqual(subject.Parent.Type.Type, "virtualNetworks"); + Assert.AreEqual(subject.Parent.ToString(), parentResource.ToString()); + Assert.AreEqual(((ResourceGroupResourceIdentifier)subject.Parent).SubscriptionId, "0c2f6471-1bf0-4dda-aec3-cb9272f09575"); + Assert.AreEqual(Uri.UnescapeDataString(((ResourceGroupResourceIdentifier)subject.Parent).ResourceGroupName), "myRg"); + Assert.AreEqual(subject.Parent.ResourceType.Namespace, "Microsoft.Network"); + Assert.AreEqual(subject.Parent.ResourceType.Type, "virtualNetworks"); Assert.AreEqual(Uri.UnescapeDataString(subject.Parent.Name), parentName); } [TestCase("UnformattedString", Description ="Too Few Elements")] [TestCase("/subs/sub1/rgs/rg1/", Description = "No known parts")] - [TestCase("/subscriptions/sub1/resourceGroups", Description = "Too few parts")] + [TestCase("/subscriptions/sub1/rgs/rg1/", Description = "Subscription not a Guid")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/resourceGroups", Description = "Too few parts")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/providers/Contoso.Widgets/widgets", Description = "Subscription resource with too few parts")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/widgets/myWidget", Description = "Subscription resource with invalid child")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/resourceGroups/myRg/widgets", Description = "ResourceGroup ID with Too few parts")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/resourceGroups/myRg/widgets/myWidget", Description = "ResourceGroup ID with invalid child")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/resourceGroups/myRg/providers/Microsoft.Widgets/widgets", Description = "ResourceGroup provider ID with Too few parts")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/incomplete", Description = "Too few parts for location resource")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/providers/incomplete", Description = "Too few parts for location resource")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/providers/myProvider/myResource/myResourceName/providers/incomplete", Description = "Too few parts for location resource")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/resourceGroups/myRg/providers/Company.MyProvider/myResources/myResourceName/providers/incomplete", Description = "Too few parts for resource group resource")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/providers/Company.MyProvider/myResources/myResourceName/providers/incomplete", Description = "Too few parts for subscription resource")] + [TestCase("/providers/Company.MyProvider/myResources/myResourceName/providers/incomplete", Description = "Too few parts for tenant resource")] public void ThrowsOnInvalidUri(string resourceId) { Assert.Throws(new TestDelegate(() => ConvertToResourceId(resourceId))); } + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/myResourceType/myResourceName", Description = "location child resource")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/myResourceType/myResourceName/mySingletonResource", Description = "location child singleton resource")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/providers/myProvider/myResourceType/myResourceName", Description = "location provider resource")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/providers/myProvider/myResourceType/myResourceName/myChildResource/myChildResourceName", Description = "location provider child resource")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/locations/westus2/providers/myProvider/myResourceType/myResourceName/providers/mySecondNamespace/myChildResource/myChildResourceName", Description = "location extension resource")] + public void CanParseValidLocationResource(string resourceId) + { + var id = ConvertToResourceId(resourceId); + Assert.AreEqual(id.ToString(), resourceId); + } + + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/providers/Contoso.Widgets/widgets/myWidget/configuration", Description ="singleton homed in a subscription resource")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/providers/Contoso.Widgets/widgets/myWidget/providers/Contoso.Extensions/extensions/myExtension", Description = "Extension over a subscription resource")] + [TestCase("/subscriptions/17fecd63-33d8-4e43-ac6f-0aafa111b38d/providers/Contoso.Widgets/widgets/myWidget/flanges/myFlange", Description = "Child of a subscription resource")] + public void CanParseValidSubscriptionResource( string resourceId) + { + SubscriptionResourceIdentifier subscription = resourceId; + Assert.AreEqual(resourceId.ToString(), resourceId); + } + + [TestCase("/providers/Contoso.Widgets/widgets/myWidget/configuration", Description = "singleton homed in a tenant resource")] + [TestCase("/providers/Contoso.Widgets/widgets/myWidget/providers/Contoso.Extensions/extensions/myExtension", Description = "Extension over a subscription resource")] + [TestCase("/providers/Contoso.Widgets/widgets/myWidget/flanges/myFlange", Description = "Child of a subscription resource")] + public void CanParseValidTenantResource(string resourceId) + { + TenantResourceIdentifier tenant = resourceId; + Assert.AreEqual(resourceId.ToString(), resourceId); + } + public ResourceIdentifier ConvertToResourceId(string resourceId) { ResourceIdentifier subject = resourceId; @@ -205,8 +246,8 @@ public ResourceIdentifier ConvertToResourceId(string resourceId) [TestCase(false, "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test/providers/Microsoft.Web/sites/autoreport", "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/nbhatia_test")] public void CheckHashCode(bool expected, string resourceId1, string resourceId2) { - ResourceIdentifier resourceIdentifier1 = new ResourceIdentifier(resourceId1); - ResourceIdentifier resourceIdentifier2 = new ResourceIdentifier(resourceId2); + ResourceIdentifier resourceIdentifier1 = new ResourceGroupResourceIdentifier(resourceId1); + ResourceIdentifier resourceIdentifier2 = new ResourceGroupResourceIdentifier(resourceId2); Assert.AreEqual(expected, resourceIdentifier1.GetHashCode() == resourceIdentifier2.GetHashCode()); } @@ -215,6 +256,7 @@ public void CheckHashCode(bool expected, string resourceId1, string resourceId2) [TestCase(null, null, true)] [TestCase(TrackedResourceId, ChildResourceId, false)] [TestCase(ChildResourceId, TrackedResourceId, false)] + [TestCase(TrackedResourceId, null, false)] [TestCase(null, TrackedResourceId, false)] public void Equals(string resourceProviderID1, string resourceProviderID2, bool expected) { @@ -226,6 +268,144 @@ public void Equals(string resourceProviderID1, string resourceProviderID2, bool Assert.AreEqual(expected, ResourceIdentifier.Equals(a,b)); } + [Test] + public void EqualsObj() + { + object input = TrackedResourceId; + ResourceIdentifier resource = new ResourceGroupResourceIdentifier(TrackedResourceId); + Assert.AreEqual(true, resource.Equals(input)); + Assert.IsFalse(resource.Equals(new object())); + } + + [Test] + public void TryGetPropertiesForTenantResource() + { + TenantResourceIdentifier id1 = "/providers/Contoso.Widgets/widgets/myWidget"; + Assert.AreEqual(false, id1.TryGetSubscriptionId(out _)); + Assert.AreEqual(false, id1.TryGetLocation(out _)); + Assert.AreEqual(false, id1.TryGetResourceGroupName(out _)); + Assert.AreEqual(false, id1.TryGetParent(out _)); + TenantResourceIdentifier id2 = "/providers/Contoso.Widgets/widgets/myWidget/flages/myFlange"; + ResourceIdentifier parent; + Assert.AreEqual(true, id2.TryGetParent(out parent)); + Assert.AreEqual(true, id1.Equals(parent)); + } + + [Test] + public void TryGetPropertiesForSubscriptionResource() + { + SubscriptionResourceIdentifier id1 = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/providers/Contoso.Widgets/widgets/myWidget"; + string subscription; + Assert.AreEqual(true, id1.TryGetSubscriptionId(out subscription)); + Assert.AreEqual("6b085460-5f21-477e-ba44-1035046e9101", subscription); + Assert.AreEqual(false, id1.TryGetLocation(out _)); + Assert.AreEqual(false, id1.TryGetResourceGroupName(out _)); + ResourceIdentifier expectedId = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101"; + ResourceIdentifier parentId; + Assert.AreEqual(true, id1.TryGetParent(out parentId)); + Assert.IsTrue(expectedId.Equals(parentId)); + } + + [Test] + public void TryGetPropertiesForLocationResource() + { + LocationResourceIdentifier id1 = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2/providers/Contoso.Widgets/widgets/myWidget"; + string subscription; + Assert.AreEqual(true, id1.TryGetSubscriptionId(out subscription)); + Assert.AreEqual("6b085460-5f21-477e-ba44-1035046e9101", subscription); + LocationData location; + Assert.AreEqual(true, id1.TryGetLocation(out location)); + Assert.AreEqual(LocationData.WestUS2, location); + Assert.AreEqual(false, id1.TryGetResourceGroupName(out _)); + ResourceIdentifier expectedId = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2"; + ResourceIdentifier parentId; + Assert.AreEqual(true, id1.TryGetParent(out parentId)); + Assert.IsTrue(expectedId.Equals(parentId)); + } + + [Test] + public void TryGetPropertiesForResourceGroupResource() + { + ResourceGroupResourceIdentifier id1 = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg/providers/Contoso.Widgets/widgets/myWidget"; + string subscription; + Assert.AreEqual(true, id1.TryGetSubscriptionId(out subscription)); + Assert.AreEqual("6b085460-5f21-477e-ba44-1035046e9101", subscription); + Assert.AreEqual(false, id1.TryGetLocation(out _)); + string resourceGroupName; + Assert.AreEqual(true, id1.TryGetResourceGroupName(out resourceGroupName)); + Assert.AreEqual("myRg", resourceGroupName); + ResourceIdentifier expectedId = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg"; + ResourceIdentifier parentId; + Assert.AreEqual(true, id1.TryGetParent(out parentId)); + Assert.IsTrue(expectedId.Equals(parentId)); + } + + [TestCase("/providers/Contoso.Widgets/widgets/myWidget", null, null, null, null, Description = "TenantResourceIdentifier")] + [TestCase("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/providers/Contoso.Widgets/widgets/myWidget", + "6b085460-5f21-477e-ba44-1035046e9101", null, null, "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101", + Description = "SubscriptionResourceIdentifier")] + [TestCase("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2/providers/Contoso.Widgets/widgets/myWidget", + "6b085460-5f21-477e-ba44-1035046e9101", "westus2", null, "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2", + Description = "LocationResourceIdentifier")] + [TestCase("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg/providers/Contoso.Widgets/widgets/myWidget", + "6b085460-5f21-477e-ba44-1035046e9101", null, "myRg", "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg", + Description = "ResourceGroupResourceIdentifier")] + public void TryGetPropertiesForGenericResource(string resourceId, string subscription, string location, string resourceGroup, string parent) + { + ResourceIdentifier id1 = resourceId; + string outputSubscription; + Assert.AreEqual(!(subscription is null), id1.TryGetSubscriptionId(out outputSubscription)); + if (!(subscription is null)) + Assert.AreEqual(subscription, outputSubscription); + LocationData outputLocation; + Assert.AreEqual(!(location is null), id1.TryGetLocation(out outputLocation)); + if (!(location is null)) + Assert.AreEqual(location, outputLocation.Name); + string outputResourceGroup; + Assert.AreEqual(!(resourceGroup is null), id1.TryGetResourceGroupName(out outputResourceGroup)); + if (!(resourceGroup is null)) + Assert.AreEqual(resourceGroup, outputResourceGroup); + ResourceIdentifier outputParent; + Assert.AreEqual(!(parent is null), id1.TryGetParent(out outputParent)); + if (!(parent is null)) + Assert.AreEqual(parent, outputParent.ToString()); + } + + [TestCase("/providers/Contoso.Widgets//widgets/myWidget", Description = "TenantResourceIdentifier")] + [TestCase("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/providers//Contoso.Widgets/widgets/myWidget", + Description = "SubscriptionResourceIdentifier")] + [TestCase("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101//locations/westus2/providers/Contoso.Widgets/widgets/myWidget", + Description = "LocationResourceIdentifier")] + [TestCase("/subscriptions//6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg/providers/Contoso.Widgets/widgets/myWidget", + Description = "ResourceGroupResourceIdentifier")] + public void ResourceIdRetainsOriginalInput(string resourceId) + { + ResourceIdentifier id = resourceId; + Assert.AreEqual(id.ToString(), resourceId); + } + + [Test] + public void ThrowOnMistypedResource() + { + TenantResourceIdentifier tenant; + Assert.Throws(() => tenant = new TenantResourceIdentifier("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101")); + Assert.Throws(() => tenant = new TenantResourceIdentifier("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2")); + Assert.Throws(() => tenant = new TenantResourceIdentifier("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg")); + Assert.DoesNotThrow(() => tenant = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101"); + Assert.DoesNotThrow(() => tenant = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2"); + Assert.DoesNotThrow(() => tenant = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg"); + SubscriptionResourceIdentifier subscription; + Assert.Throws(() => subscription = "/providers/Contoso.Widgets/widgets/myWidget"); + Assert.Throws(() => subscription = new SubscriptionResourceIdentifier("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2")); + Assert.Throws(() => subscription = new SubscriptionResourceIdentifier("/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg")); + Assert.DoesNotThrow(() => subscription = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/locations/westus2"); + Assert.DoesNotThrow(() => subscription = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101/resourceGroups/myRg"); + ResourceGroupResourceIdentifier group; + Assert.Throws(() => group = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101"); + LocationResourceIdentifier location; + Assert.Throws(() => location = "/subscriptions/6b085460-5f21-477e-ba44-1035046e9101"); + } + [TestCase(TrackedResourceId, TrackedResourceId, 0)] [TestCase(TrackedResourceId, ChildResourceId, -1)] [TestCase(ChildResourceId, TrackedResourceId, 1)] @@ -235,11 +415,10 @@ public void Equals(string resourceProviderID1, string resourceProviderID2, bool public void CompareToResourceProvider(string resourceProviderID1, string resourceProviderID2, int expected) { ResourceIdentifier a = resourceProviderID1; - ResourceIdentifier b = resourceProviderID2; + ResourceIdentifier b = (ResourceIdentifier)resourceProviderID2; if (a != null) Assert.AreEqual(expected, a.CompareTo(b)); - Assert.AreEqual(expected, ResourceIdentifier.CompareTo(a, b)); } [TestCase(TrackedResourceId, TrackedResourceId, 0)] @@ -254,8 +433,209 @@ public void CompareToString(string resourceProviderID1, string resourceProviderI string b = resourceProviderID2; if (a != null) Assert.AreEqual(expected, a.CompareTo(b)); + } + + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget", "Microsoft.Authorization", "roleAssignments", "MyRoleAssignemnt")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", "roleAssignments", "MyRoleAssignemnt")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", null, "roleAssignments", "MyRoleAssignemnt")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", null, "MyRoleAssignemnt")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", "roleAssignments", null)] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "", "roleAssignments", "MyRoleAssignemnt")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", " ", "MyRoleAssignemnt")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", "roleAssignments", "")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft/Authorization", "roleAssignments", "MyRoleAssignemnt")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", "roleA/ssignments", "MyRoleAssignemnt")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "Microsoft.Authorization", "roleAssignments", "MyRole/Assignemnt")] - Assert.AreEqual(expected, ResourceIdentifier.CompareTo(a, b)); + public void TestAppendTenantProviderResource(string resourceId, string providerNamespace, string resourceTypeName, string resourceName) + { + TenantResourceIdentifier resource = resourceId; + if (providerNamespace is null || resourceTypeName is null || resourceName is null) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName)); + else if (string.IsNullOrWhiteSpace(providerNamespace) || string.IsNullOrWhiteSpace(resourceTypeName) || string.IsNullOrWhiteSpace(resourceName)) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName)); + else if (providerNamespace.Contains("/") || resourceTypeName.Contains("/") || resourceName.Contains("/")) + Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName)); + else + { + var expected = $"{resourceId}/providers/{providerNamespace}/{resourceTypeName}/{resourceName}"; + Assert.AreEqual(expected, resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName).ToString()); + } + } + + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget", "wheels", "Wheel1")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "wheels", "Wheel2")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", null, "wheel2")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "wheels", null)] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "", "wheel2")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "wheels", " ")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "wheels/spokes", "wheel2")] + [TestCase("/providers/Microsoft.Widgets/widgets/MyWidget/things/MyThing", "wheels", "wheel1/wheel2")] + public void TestAppendTenantChildResource(string resourceId, string childTypeName, string childResourceName) + { + TenantResourceIdentifier resource = resourceId; + if (childTypeName is null || childResourceName is null) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName)); + else if (string.IsNullOrWhiteSpace(childTypeName) || string.IsNullOrWhiteSpace(childResourceName)) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName)); + else if (childTypeName.Contains("/") || childResourceName.Contains("/") ) + Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendChildResource(childTypeName, childResourceName)); + else + { + var expected = $"{resourceId}/{childTypeName}/{childResourceName}"; + Assert.AreEqual(expected, resource.AppendChildResource(childTypeName, childResourceName).ToString()); + } + } + + [TestCase(SubscriptionResourceId, "Microsoft.Authorization", "roleAssignments", "MyRoleAssignemnt")] + [TestCase(SubscriptionResourceId, null, "roleAssignments", "MyRoleAssignemnt")] + [TestCase(SubscriptionResourceId, "Microsoft.Authorization", null, "MyRoleAssignemnt")] + [TestCase(SubscriptionResourceId, "Microsoft.Authorization", "roleAssignments", null)] + [TestCase(SubscriptionResourceId, "", "roleAssignments", "MyRoleAssignemnt")] + [TestCase(SubscriptionResourceId, "Microsoft.Authorization", " ", "MyRoleAssignemnt")] + [TestCase(SubscriptionResourceId, "Microsoft.Authorization", "roleAssignments", "")] + [TestCase(SubscriptionResourceId, "Microsoft/Authorization", "roleAssignments", "MyRoleAssignemnt")] + [TestCase(SubscriptionResourceId, "Microsoft.Authorization", "roleA/ssignments", "MyRoleAssignemnt")] + [TestCase(SubscriptionResourceId, "Microsoft.Authorization", "roleAssignments", "MyRole/Assignemnt")] + + public void TestAppendSubscriptionProviderResource(string resourceId, string providerNamespace, string resourceTypeName, string resourceName) + { + SubscriptionResourceIdentifier resource = resourceId; + if (providerNamespace is null || resourceTypeName is null || resourceName is null) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName)); + else if (string.IsNullOrWhiteSpace(providerNamespace) || string.IsNullOrWhiteSpace(resourceTypeName) || string.IsNullOrWhiteSpace(resourceName)) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName)); + else if (providerNamespace.Contains("/") || resourceTypeName.Contains("/") || resourceName.Contains("/")) + Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName)); + else + { + var expected = $"{resourceId}/providers/{providerNamespace}/{resourceTypeName}/{resourceName}"; + Assert.AreEqual(expected, resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName).ToString()); + } + } + + [TestCase(SubscriptionResourceId, "wheels", "Wheel2")] + [TestCase(SubscriptionResourceId, null, "wheel2")] + [TestCase(SubscriptionResourceId, "wheels", null)] + [TestCase(SubscriptionResourceId, "", "wheel2")] + [TestCase(SubscriptionResourceId, "wheels", " ")] + [TestCase(SubscriptionResourceId, "wheels/spokes", "wheel2")] + [TestCase(SubscriptionResourceId, "wheels", "wheel1/wheel2")] + public void TestAppendSubscriptionChildResource(string resourceId, string childTypeName, string childResourceName) + { + SubscriptionResourceIdentifier resource = resourceId; + if (childTypeName is null || childResourceName is null) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName)); + else if (string.IsNullOrWhiteSpace(childTypeName) || string.IsNullOrWhiteSpace(childResourceName)) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName)); + else if (childTypeName.Contains("/") || childResourceName.Contains("/")) + Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendChildResource(childTypeName, childResourceName)); + else + { + var expected = $"{resourceId}/{childTypeName}/{childResourceName}"; + Assert.AreEqual(expected, resource.AppendChildResource(childTypeName, childResourceName).ToString()); + } + } + + [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", "roleAssignments", "MyRoleAssignemnt")] + [TestCase(ResourceGroupResourceId, null, "roleAssignments", "MyRoleAssignemnt")] + [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", null, "MyRoleAssignemnt")] + [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", "roleAssignments", null)] + [TestCase(ResourceGroupResourceId, "", "roleAssignments", "MyRoleAssignemnt")] + [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", " ", "MyRoleAssignemnt")] + [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", "roleAssignments", "")] + [TestCase(ResourceGroupResourceId, "Microsoft/Authorization", "roleAssignments", "MyRoleAssignemnt")] + [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", "roleA/ssignments", "MyRoleAssignemnt")] + [TestCase(ResourceGroupResourceId, "Microsoft.Authorization", "roleAssignments", "MyRole/Assignemnt")] + + public void TestAppendResourceGroupProviderResource(string resourceId, string providerNamespace, string resourceTypeName, string resourceName) + { + ResourceGroupResourceIdentifier resource = resourceId; + if (providerNamespace is null || resourceTypeName is null || resourceName is null) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName)); + else if (string.IsNullOrWhiteSpace(providerNamespace) || string.IsNullOrWhiteSpace(resourceTypeName) || string.IsNullOrWhiteSpace(resourceName)) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName)); + else if (providerNamespace.Contains("/") || resourceTypeName.Contains("/") || resourceName.Contains("/")) + Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName)); + else + { + var expected = $"{resourceId}/providers/{providerNamespace}/{resourceTypeName}/{resourceName}"; + Assert.AreEqual(expected, resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName).ToString()); + } + } + + [TestCase(ResourceGroupResourceId, "wheels", "Wheel1")] + [TestCase(ResourceGroupResourceId, "wheels", "Wheel2")] + [TestCase(ResourceGroupResourceId, null, "wheel2")] + [TestCase(ResourceGroupResourceId, "wheels", null)] + [TestCase(ResourceGroupResourceId, "", "wheel2")] + [TestCase(ResourceGroupResourceId, "wheels", " ")] + [TestCase(ResourceGroupResourceId, "wheels/spokes", "wheel2")] + [TestCase(ResourceGroupResourceId, "wheels", "wheel1/wheel2")] + public void TestAppendResourceGroupChildResource(string resourceId, string childTypeName, string childResourceName) + { + ResourceGroupResourceIdentifier resource = resourceId; + if (childTypeName is null || childResourceName is null) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName)); + else if (string.IsNullOrWhiteSpace(childTypeName) || string.IsNullOrWhiteSpace(childResourceName)) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName)); + else if (childTypeName.Contains("/") || childResourceName.Contains("/")) + Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendChildResource(childTypeName, childResourceName)); + else + { + var expected = $"{resourceId}/{childTypeName}/{childResourceName}"; + Assert.AreEqual(expected, resource.AppendChildResource(childTypeName, childResourceName).ToString()); + } + } + + [TestCase(LocationResourceId, "Microsoft.Authorization", "roleAssignments", "MyRoleAssignemnt")] + [TestCase(LocationResourceId, null, "roleAssignments", "MyRoleAssignemnt")] + [TestCase(LocationResourceId, "Microsoft.Authorization", null, "MyRoleAssignemnt")] + [TestCase(LocationResourceId, "Microsoft.Authorization", "roleAssignments", null)] + [TestCase(LocationResourceId, "", "roleAssignments", "MyRoleAssignemnt")] + [TestCase(LocationResourceId, "Microsoft.Authorization", " ", "MyRoleAssignemnt")] + [TestCase(LocationResourceId, "Microsoft.Authorization", "roleAssignments", "")] + [TestCase(LocationResourceId, "Microsoft/Authorization", "roleAssignments", "MyRoleAssignemnt")] + [TestCase(LocationResourceId, "Microsoft.Authorization", "roleA/ssignments", "MyRoleAssignemnt")] + [TestCase(LocationResourceId, "Microsoft.Authorization", "roleAssignments", "MyRole/Assignemnt")] + + public void TestAppendLocationProviderResource(string resourceId, string providerNamespace, string resourceTypeName, string resourceName) + { + LocationResourceIdentifier resource = resourceId; + if (providerNamespace is null || resourceTypeName is null || resourceName is null) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName)); + else if (string.IsNullOrWhiteSpace(providerNamespace) || string.IsNullOrWhiteSpace(resourceTypeName) || string.IsNullOrWhiteSpace(resourceName)) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName)); + else if (providerNamespace.Contains("/") || resourceTypeName.Contains("/") || resourceName.Contains("/")) + Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName)); + else + { + var expected = $"{resourceId}/providers/{providerNamespace}/{resourceTypeName}/{resourceName}"; + Assert.AreEqual(expected, resource.AppendProviderResource(providerNamespace, resourceTypeName, resourceName).ToString()); + } + } + + [TestCase(LocationResourceId, "wheels", "Wheel1")] + [TestCase(LocationResourceId, null, "wheel2")] + [TestCase(LocationResourceId, "wheels", null)] + [TestCase(LocationResourceId, "", "wheel2")] + [TestCase(LocationResourceId, "wheels", " ")] + [TestCase(LocationResourceId, "wheels/spokes", "wheel2")] + [TestCase(LocationResourceId, "wheels", "wheel1/wheel2")] + public void TestAppendLocationChildResource(string resourceId, string childTypeName, string childResourceName) + { + LocationResourceIdentifier resource = resourceId; + if (childTypeName is null || childResourceName is null) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName)); + else if (string.IsNullOrWhiteSpace(childTypeName) || string.IsNullOrWhiteSpace(childResourceName)) + Assert.Throws(typeof(ArgumentNullException), () => resource.AppendChildResource(childTypeName, childResourceName)); + else if (childTypeName.Contains("/") || childResourceName.Contains("/")) + Assert.Throws(typeof(ArgumentOutOfRangeException), () => resource.AppendChildResource(childTypeName, childResourceName)); + else + { + var expected = $"{resourceId}/{childTypeName}/{childResourceName}"; + Assert.AreEqual(expected, resource.AppendChildResource(childTypeName, childResourceName).ToString()); + } } } } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceListOperationsTest.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceListOperationsTest.cs index 594d64f300eb..a3ea91900e7c 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceListOperationsTest.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceListOperationsTest.cs @@ -107,7 +107,7 @@ private static ResourceGroupOperations GetResourceGroupOperations() private static GenericResourceExpanded GetGenericResource() { - return GetGenereicResource( + return GetGenericResource( new Dictionary { { "tag1", "value1" } }, GetSku(), GetPlan(), @@ -116,7 +116,7 @@ private static GenericResourceExpanded GetGenericResource() "Japan East"); } - private static GenericResourceExpanded GetGenereicResource( + private static GenericResourceExpanded GetGenericResource( Dictionary tags, ResourceManager.Resources.Models.Sku sku, ResourceManager.Resources.Models.Plan plan, @@ -126,14 +126,16 @@ private static GenericResourceExpanded GetGenereicResource( { var resource = new GenericResourceExpanded(); + // See TODO in GenericResourceOperations.Valide(). + //resource.Id = "/subscriptions/{subscription-id}/resourceGroups/myResourceGroup"; + var field = typeof(Resource).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic); + field.SetValue(resource, $"/subscriptions/{Guid.NewGuid().ToString()}/resourceGroups/myResourceGroup/providers/Microsoft.Widgets/widgets/myWidget"); resource.Location = location; resource.Tags.ReplaceWith(tags ?? new Dictionary()); resource.Sku = sku; resource.Plan = plan; resource.Kind = kind; resource.ManagedBy = managedBy; - var field = typeof(GenericResourceExpanded).BaseType.BaseType.GetField("k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic); - field.SetValue(resource, "/subscriptions/{subscription-id}/resourceGroups/myResourceGroup"); return resource; } } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceTests.cs b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceTests.cs index f66207971f3e..4bb596b7c7ed 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceTests.cs +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/ResourceTests.cs @@ -22,8 +22,8 @@ public class ResourceTests "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account2")] public void CompareToObject(int expected, string id1, string id2) { - TestResource resource1 = new TestResource(id1); - TestResource resource2 = new TestResource(id2); + TestResource resource1 = new TestResource(id1); + TestResource resource2 = new TestResource(id2); Assert.AreEqual(expected, resource1.CompareTo(resource2)); } @@ -41,15 +41,15 @@ public void CompareToObject(int expected, string id1, string id2) "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account2")] public void CompareToString(int expected, string id1, string id2) { - TestResource resource1 = new TestResource(id1); + TestResource resource1 = new TestResource(id1); Assert.AreEqual(expected, resource1.CompareTo(id2)); } [Test] public void CompareToNull() { - TestResource resource1 = new TestResource("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account1"); - TestResource resource2 = null; + var resource1 = new TestResource("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account1"); + TestResource resource2 = null; Assert.AreEqual(1, resource1.CompareTo(resource2)); Assert.AreEqual(1, resource1.CompareTo((string)null)); } @@ -57,8 +57,8 @@ public void CompareToNull() [Test] public void CompareToSame() { - TestResource resource1 = new TestResource("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account1"); - TestResource resource2 = resource1; + var resource1 = new TestResource("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRg/providers/Microsoft.ClassicStorage/storageAccounts/account1"); + var resource2 = resource1; Assert.AreEqual(0, resource1.CompareTo(resource2)); } } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/InvalidType.json b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/InvalidType.json index 88dc49b9af0e..a2328a4b92fa 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/InvalidType.json +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/InvalidType.json @@ -4,10 +4,10 @@ "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47", "type": "Test", "userAssignedIdentities": { - "/subscriptions/db1ab6f0-4769-tgds-930e-01e2ef9c123c/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity": { - "clientId": "9a2eaa6a-b49c-4a63-afb5-3b72e3e65422", - "principalId": "77563a98-c9d9-4f7b-a7af-592d21fa2153" - } + "/subscriptions/d96407f5-db8f-4325-b582-84ad21310bd8/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity": { + "clientId": "9a2eaa6a-b49c-4a63-afb5-3b72e3e65422", + "principalId": "77563a98-c9d9-4f7b-a7af-592d21fa2153" + } } } } diff --git a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/SystemAndUserAssignedValidMultIdentities.json b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/SystemAndUserAssignedValidMultIdentities.json index 660ab014dee5..f8084ae97d51 100644 --- a/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/SystemAndUserAssignedValidMultIdentities.json +++ b/sdk/resourcemanager/Azure.ResourceManager.Core/tests/Unit/TestAssets/Identity/SystemAndUserAssignedValidMultIdentities.json @@ -4,14 +4,14 @@ "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db40", "type": "SystemAssigned, UserAssigned", "userAssignedIdentities": { - "/subscriptions/db1ab6f0-4769-4b27-930e-01e2ef9c123z/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity0": { - "clientId": "9a2eaa6a-b49c-4c63-afb5-3b72e3e65422", - "principalId": "77563a98-c9d9-477b-a7af-592d21fa2153" - }, - "/subscriptions/db1ab6f0-4769-4b27-930e-01e2ef9cfrgh/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity1": { - "clientId": "9a2eaa6a-b49c-4c63-afb5-3b72e3c65420", - "principalId": "77563a98-c9d9-477b-a7af-592d2bfa2150" - } + "/subscriptions/1ab27dfb-d2ee-4283-b1e3-550deaebb8e4/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity0": { + "clientId": "9a2eaa6a-b49c-4c63-afb5-3b72e3e65422", + "principalId": "77563a98-c9d9-477b-a7af-592d21fa2153" + }, + "/subscriptions/d96407f5-db8f-4325-b582-84ad21310bd8/resourceGroups/tester/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testidentity1": { + "clientId": "9a2eaa6a-b49c-4c63-afb5-3b72e3c65420", + "principalId": "77563a98-c9d9-477b-a7af-592d2bfa2150" + } } } } diff --git a/sdk/resourcemanager/Proto.Client/authorization/Extensions/RoleAssignmentExtensions.cs b/sdk/resourcemanager/Proto.Client/authorization/Extensions/RoleAssignmentExtensions.cs index ca7cf83f03df..bf330f41a280 100644 --- a/sdk/resourcemanager/Proto.Client/authorization/Extensions/RoleAssignmentExtensions.cs +++ b/sdk/resourcemanager/Proto.Client/authorization/Extensions/RoleAssignmentExtensions.cs @@ -51,7 +51,7 @@ public static RoleAssignmentContainer GetRoleAssigmentContainerAtScope(this Subs /// The subscription containign the role assignment /// The target of the role assignment /// A that allows creating and listing RoleAssignments - public static RoleAssignmentContainer GetRoleAssigmentContainerAtScope(this SubscriptionOperations subscription, Resource scope) + public static RoleAssignmentContainer GetRoleAssigmentContainerAtScope(this SubscriptionOperations subscription, Resource scope) { return new RoleAssignmentContainer(subscription, scope.Id); } diff --git a/sdk/resourcemanager/Proto.Client/authorization/Placeholder/RoleAssignmentData.cs b/sdk/resourcemanager/Proto.Client/authorization/Placeholder/RoleAssignmentData.cs index f5a5b143bad7..ddb0d859acc5 100644 --- a/sdk/resourcemanager/Proto.Client/authorization/Placeholder/RoleAssignmentData.cs +++ b/sdk/resourcemanager/Proto.Client/authorization/Placeholder/RoleAssignmentData.cs @@ -9,7 +9,7 @@ namespace Proto.Authorization /// /// Placholder class containing Role assignment POCO properties. /// - public class RoleAssignmentData : Resource + public class RoleAssignmentData : Resource { private Azure.ResourceManager.Authorization.Models.RoleAssignment _model; @@ -20,7 +20,7 @@ public class RoleAssignmentData : Resource public RoleAssignmentData(Azure.ResourceManager.Authorization.Models.RoleAssignment assign) { _model = assign; - Id = assign.Id; + Id = new TenantResourceIdentifier(assign.Id); Scope = assign.Scope; RoleDefinitionId = assign.RoleDefinitionId; PrincipalId = assign.PrincipalId; @@ -61,7 +61,7 @@ public RoleAssignmentData(Azure.ResourceManager.Authorization.Models.RoleAssignm /// /// Gets or sets the identifier of the RoleAssignment. /// - public override ResourceIdentifier Id { get; protected set; } + public override TenantResourceIdentifier Id { get; protected set; } /// /// Gets the Track2 Management model associated with the data object. diff --git a/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentContainer.cs b/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentContainer.cs index 91fc04b98669..04a6be91b5ac 100644 --- a/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentContainer.cs +++ b/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentContainer.cs @@ -3,6 +3,7 @@ using Azure.ResourceManager.Authorization; using Azure.ResourceManager.Core; +using System; using System.Threading; using System.Threading.Tasks; @@ -20,6 +21,14 @@ public class RoleAssignmentContainer : ExtensionResourceContainer @@ -30,6 +39,14 @@ internal RoleAssignmentContainer(OperationsBase operations) internal RoleAssignmentContainer(OperationsBase operations, ResourceIdentifier scope) : base(operations, scope) { + // TODO: Remove this once we nio longer need to create management clients + string subscriptionId; + if (!operations.Id.TryGetSubscriptionId(out subscriptionId)) + { + subscriptionId = Guid.Empty.ToString(); + } + + Operations = new AuthorizationManagementClient(subscriptionId, BaseUri, Credential).RoleAssignments; } /// @@ -38,7 +55,7 @@ internal RoleAssignmentContainer(OperationsBase operations, ResourceIdentifier s /// /// Gets the resource type of the resource being created. /// - private RoleAssignmentsOperations Operations => new AuthorizationManagementClient(Id.Subscription, BaseUri, Credential).RoleAssignments; + private RoleAssignmentsOperations Operations { get; } /// /// Create a role assignment. This method blocks until the RoleAssignment is created on the service. diff --git a/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentOperations.cs b/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentOperations.cs index 555de7279a9a..adc08ef924d5 100644 --- a/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentOperations.cs +++ b/sdk/resourcemanager/Proto.Client/authorization/RoleAssignmentOperations.cs @@ -4,6 +4,7 @@ using Azure; using Azure.ResourceManager.Authorization; using Azure.ResourceManager.Core; +using System; using System.Threading; using System.Threading.Tasks; @@ -27,6 +28,14 @@ public class RoleAssignmentOperations : ExtensionResourceOperationsBase @@ -37,16 +46,20 @@ internal RoleAssignmentOperations(GenericResourceOperations genericOperations) internal RoleAssignmentOperations(OperationsBase operation, ResourceIdentifier id) : base(operation, id) { + string subscriptionId; + if (!Id.TryGetSubscriptionId(out subscriptionId)) + { + // TODO: Remove this once we have swapped in the REST client + subscriptionId = Guid.Empty.ToString(); + } + + Operations = new AuthorizationManagementClient(subscriptionId, BaseUri, Credential).RoleAssignments; } /// protected override ResourceType ValidResourceType => ResourceType; - private RoleAssignmentsOperations Operations => new AuthorizationManagementClient( - Id.Subscription, - BaseUri, - Credential, - ClientOptions.Convert()).RoleAssignments; + private RoleAssignmentsOperations Operations { get; } /// public ArmResponse Delete(CancellationToken cancellationToken = default) diff --git a/sdk/resourcemanager/Proto.Client/billing/BillingAccountOperations.cs b/sdk/resourcemanager/Proto.Client/billing/BillingAccountOperations.cs index cb84ce0b36b7..4290c1278e7f 100644 --- a/sdk/resourcemanager/Proto.Client/billing/BillingAccountOperations.cs +++ b/sdk/resourcemanager/Proto.Client/billing/BillingAccountOperations.cs @@ -13,7 +13,7 @@ namespace Proto.Billing /// /// A class representing the operations that can be performed over a specific availability set. /// - public class BillingAccountOperations : ResourceOperationsBase + public class BillingAccountOperations : ResourceOperationsBase { /// /// Initializes a new instance of the class. diff --git a/sdk/resourcemanager/Proto.Client/billing/Placeholder/BillingAccountData.cs b/sdk/resourcemanager/Proto.Client/billing/Placeholder/BillingAccountData.cs index 8524744289da..5ce6b2ff31bc 100644 --- a/sdk/resourcemanager/Proto.Client/billing/Placeholder/BillingAccountData.cs +++ b/sdk/resourcemanager/Proto.Client/billing/Placeholder/BillingAccountData.cs @@ -8,7 +8,7 @@ namespace Proto.Billing /// /// A class representing the availability set data model. /// - public class BillingAccountData : TrackedResource + public class BillingAccountData : TrackedResource { /// diff --git a/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetContainer.cs b/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetContainer.cs index f8c42bf617ee..7c7685105398 100644 --- a/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetContainer.cs +++ b/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetContainer.cs @@ -10,7 +10,7 @@ namespace Proto.Compute /// /// A class representing collection of availability set and their operations over a resource group. /// - public class AvailabilitySetContainer : ResourceContainerBase + public class AvailabilitySetContainer : ResourceContainerBase { /// /// Initializes a new instance of the class. @@ -24,10 +24,15 @@ internal AvailabilitySetContainer(ResourceGroupOperations resourceGroup) /// protected override ResourceType ValidResourceType => ResourceGroupOperations.ResourceType; + /// + /// Typed Resource Identifier for the container. + /// + public new ResourceGroupResourceIdentifier Id => base.Id as ResourceGroupResourceIdentifier; + /// public override ArmResponse CreateOrUpdate(string name, AvailabilitySetData resourceDetails, CancellationToken cancellationToken = default) { - var response = Operations.CreateOrUpdate(Id.ResourceGroup, name, resourceDetails.Model); + var response = Operations.CreateOrUpdate(Id.ResourceGroupName, name, resourceDetails.Model); return new PhArmResponse( response, a => new AvailabilitySet(Parent, new AvailabilitySetData(a))); @@ -36,7 +41,8 @@ public override ArmResponse CreateOrUpdate(string name, Availab /// public async override Task> CreateOrUpdateAsync(string name, AvailabilitySetData resourceDetails, CancellationToken cancellationToken = default) { - var response = await Operations.CreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false); + var containerId = Id as ResourceGroupResourceIdentifier; + var response = await Operations.CreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false); return new PhArmResponse( response, a => new AvailabilitySet(Parent, new AvailabilitySetData(a))); @@ -46,7 +52,7 @@ public async override Task> CreateOrUpdateAsync(str public override ArmOperation StartCreateOrUpdate(string name, AvailabilitySetData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - Operations.CreateOrUpdate(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken), + Operations.CreateOrUpdate(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken), a => new AvailabilitySet(Parent, new AvailabilitySetData(a))); } @@ -54,7 +60,7 @@ public override ArmOperation StartCreateOrUpdate(string name, A public async override Task> StartCreateOrUpdateAsync(string name, AvailabilitySetData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - await Operations.CreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false), + await Operations.CreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false), a => new AvailabilitySet(Parent, new AvailabilitySetData(a))); } @@ -64,9 +70,9 @@ await Operations.CreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails.Mod /// The sku name of the resource. /// The location of the resource. /// A builder with and . - public ArmBuilder Construct(string skuName, LocationData location = null) + public ArmBuilder Construct(string skuName, LocationData location = null) { - var parent = GetParentResource(); + var parent = GetParentResource(); var availabilitySet = new Azure.ResourceManager.Compute.Models.AvailabilitySet(location ?? parent.Data.Location) { PlatformUpdateDomainCount = 5, @@ -74,7 +80,7 @@ public ArmBuilder Construct(string skuName Sku = new Azure.ResourceManager.Compute.Models.Sku() { Name = skuName } }; - return new ArmBuilder(this, new AvailabilitySetData(availabilitySet)); + return new ArmBuilder(this, new AvailabilitySetData(availabilitySet)); } /// @@ -135,7 +141,7 @@ public AsyncPageable ListAsync(string nameFilter, int? top = nu private AvailabilitySetsOperations Operations => new ComputeManagementClient( BaseUri, - Id.Subscription, + Id.SubscriptionId, Credential, ClientOptions.Convert()).AvailabilitySets; @@ -143,14 +149,14 @@ public AsyncPageable ListAsync(string nameFilter, int? top = nu /// public override ArmResponse Get(string availabilitySetName, CancellationToken cancellationToken = default) { - return new PhArmResponse(Operations.Get(Id.ResourceGroup, availabilitySetName), + return new PhArmResponse(Operations.Get(Id.ResourceGroupName, availabilitySetName), g => new AvailabilitySet(Parent, new AvailabilitySetData(g))); } /// public override async Task> GetAsync(string availabilitySetName, CancellationToken cancellationToken = default) { - return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroup, availabilitySetName, cancellationToken), + return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroupName, availabilitySetName, cancellationToken), g => new AvailabilitySet(Parent, new AvailabilitySetData(g))); } } diff --git a/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetOperations.cs b/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetOperations.cs index 35db75c5c344..430270006a0a 100644 --- a/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetOperations.cs +++ b/sdk/resourcemanager/Proto.Client/compute/AvailabilitySetOperations.cs @@ -12,7 +12,7 @@ namespace Proto.Compute /// /// A class representing the operations that can be performed over a specific availability set. /// - public class AvailabilitySetOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource + public class AvailabilitySetOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource { /// /// Initializes a new instance of the class. @@ -29,7 +29,7 @@ internal AvailabilitySetOperations(GenericResourceOperations genericOperations) /// The client parameters to use in these operations. /// The name of the availability set to use. internal AvailabilitySetOperations(ResourceGroupOperations resourceGroup, string availabilitySetName) - : base(resourceGroup, $"{resourceGroup.Id}/providers/Microsoft.Compute/availabilitySets/{availabilitySetName}") + : base(resourceGroup, resourceGroup.Id.AppendProviderResource(ResourceType.Namespace, ResourceType.Type, availabilitySetName)) { } @@ -38,7 +38,7 @@ internal AvailabilitySetOperations(ResourceGroupOperations resourceGroup, string /// /// The client parameters to use in these operations. /// The identifier of the resource that is the target of operations. - protected AvailabilitySetOperations(ResourceOperationsBase options, ResourceIdentifier id) + protected AvailabilitySetOperations(ResourceOperationsBase options, ResourceGroupResourceIdentifier id) : base(options, id) { } @@ -53,39 +53,39 @@ protected AvailabilitySetOperations(ResourceOperationsBase options, ResourceIden private AvailabilitySetsOperations Operations => new ComputeManagementClient( BaseUri, - Id.Subscription, + Id.SubscriptionId, Credential, ClientOptions.Convert()).AvailabilitySets; /// public ArmResponse Delete(CancellationToken cancellationToken = default) { - return new ArmResponse(Operations.Delete(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmResponse(Operations.Delete(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// public async Task> DeleteAsync(CancellationToken cancellationToken = default) { - return new ArmResponse(await Operations.DeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmResponse(await Operations.DeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// public ArmOperation StartDelete(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(Operations.Delete(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(Operations.Delete(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// public async Task> StartDeleteAsync(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(await Operations.DeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(await Operations.DeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// public override ArmResponse Get(CancellationToken cancellationToken = default) { return new PhArmResponse( - Operations.Get(Id.ResourceGroup, Id.Name), + Operations.Get(Id.ResourceGroupName, Id.Name), a => new AvailabilitySet(this, new AvailabilitySetData(a))); } @@ -93,7 +93,7 @@ public override ArmResponse Get(CancellationToken cancellationT public async override Task> GetAsync(CancellationToken cancellationToken = default) { return new PhArmResponse( - await Operations.GetAsync(Id.ResourceGroup, Id.Name, cancellationToken), + await Operations.GetAsync(Id.ResourceGroupName, Id.Name, cancellationToken), a => new AvailabilitySet(this, new AvailabilitySetData(a))); } @@ -105,7 +105,7 @@ await Operations.GetAsync(Id.ResourceGroup, Id.Name, cancellationToken), public ArmResponse Update(AvailabilitySetUpdate patchable, CancellationToken cancellationToken = default) { return new PhArmResponse( - Operations.Update(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.Update(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), a => new AvailabilitySet(this, new AvailabilitySetData(a))); } @@ -118,7 +118,7 @@ public ArmResponse Update(AvailabilitySetUpdate patchable, Canc public async Task> UpdateAsync(AvailabilitySetUpdate patchable, CancellationToken cancellationToken = default) { return new PhArmResponse( - await Operations.UpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), a => new AvailabilitySet(this, new AvailabilitySetData(a))); } @@ -130,7 +130,7 @@ await Operations.UpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationT public ArmOperation StartUpdate(AvailabilitySetUpdate patchable, CancellationToken cancellationToken = default) { return new PhArmOperation( - Operations.Update(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.Update(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), a => new AvailabilitySet(this, new AvailabilitySetData(a))); } @@ -143,7 +143,7 @@ public ArmOperation StartUpdate(AvailabilitySetUpdate patchable public async Task> StartUpdateAsync(AvailabilitySetUpdate patchable, CancellationToken cancellationToken = default) { return new PhArmOperation( - await Operations.UpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), a => new AvailabilitySet(this, new AvailabilitySetData(a))); } diff --git a/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilder.cs b/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilder.cs index 79a31fecf2cf..2a9ebfaabcc4 100644 --- a/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilder.cs +++ b/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilder.cs @@ -25,7 +25,7 @@ public VirtualMachineModelBuilder(VirtualMachineContainer containerOperations, V /// /// The disk to attach. /// An instance of - public VirtualMachineModelBuilderBase AttachDataDisk(TrackedResource azureEntity) + public VirtualMachineModelBuilderBase AttachDataDisk(TrackedResource azureEntity) { throw new NotImplementedException(); } diff --git a/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilderBase.cs b/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilderBase.cs index b3ee5ee648f8..013100e0a95d 100644 --- a/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilderBase.cs +++ b/sdk/resourcemanager/Proto.Client/compute/Convenience/VirtualMachineModelBuilderBase.cs @@ -5,7 +5,7 @@ namespace Proto.Compute.Convenience /// /// A class representing the base for a builder object to help create a virtual machine. /// - public abstract class VirtualMachineModelBuilderBase : ArmBuilder + public abstract class VirtualMachineModelBuilderBase : ArmBuilder { /// /// Initializes a new instance of . diff --git a/sdk/resourcemanager/Proto.Client/compute/Extensions/ArmClientExtensions.cs b/sdk/resourcemanager/Proto.Client/compute/Extensions/ArmClientExtensions.cs index 1601ce928cc8..e283e86aba45 100644 --- a/sdk/resourcemanager/Proto.Client/compute/Extensions/ArmClientExtensions.cs +++ b/sdk/resourcemanager/Proto.Client/compute/Extensions/ArmClientExtensions.cs @@ -17,14 +17,14 @@ public static class ArmClientExtensions /// Returns an object representing the operations that can be performed over a specific . /// ResourceIdentifier provided is not for an AvailabilitySet. /// ResourceIdentifier cannot be null. - public static AvailabilitySetOperations GetAvailabilitySetOperations(this AzureResourceManagerClient client, ResourceIdentifier resourceId) + public static AvailabilitySetOperations GetAvailabilitySetOperations(this AzureResourceManagerClient client, ResourceGroupResourceIdentifier resourceId) { if (resourceId is null) throw new ArgumentNullException(nameof(resourceId)); - if (resourceId.Type != AvailabilitySetOperations.ResourceType) - throw new ArgumentException($"{nameof(resourceId.Type)} provided is not for an AvailabilitySet.", nameof(resourceId.Type)); + if (resourceId.ResourceType != AvailabilitySetOperations.ResourceType) + throw new ArgumentException($"{nameof(resourceId.ResourceType)} provided is not for an AvailabilitySet.", nameof(resourceId.ResourceType)); - return client.GetSubscriptionOperations(resourceId.Subscription).GetResourceGroupOperations(resourceId.ResourceGroup).GetAvailabilitySetOperations(resourceId.Name); + return client.GetSubscriptionOperations(resourceId.SubscriptionId).GetResourceGroupOperations(resourceId.ResourceGroupName).GetAvailabilitySetOperations(resourceId.Name); } /// @@ -35,14 +35,14 @@ public static AvailabilitySetOperations GetAvailabilitySetOperations(this AzureR /// Returns an object representing the operations that can be performed over a specific . /// ResourceIdentifier provided is not for a VirtualMachine. /// ResourceIdentifier cannot be null. - public static VirtualMachineOperations GetVirtualMachineOperations(this AzureResourceManagerClient client, ResourceIdentifier resourceId) + public static VirtualMachineOperations GetVirtualMachineOperations(this AzureResourceManagerClient client, ResourceGroupResourceIdentifier resourceId) { if (resourceId is null) throw new ArgumentNullException(nameof(resourceId)); - if (resourceId.Type != VirtualMachineOperations.ResourceType) - throw new ArgumentException($"{nameof(resourceId.Type)} provided is not for a VirtualMachine.", nameof(resourceId.Type)); + if (resourceId.ResourceType != VirtualMachineOperations.ResourceType) + throw new ArgumentException($"{nameof(resourceId.ResourceType)} provided is not for a VirtualMachine.", nameof(resourceId.ResourceType)); - return client.GetSubscriptionOperations(resourceId.Subscription).GetResourceGroupOperations(resourceId.ResourceGroup).GetVirtualMachineOperations(resourceId.Name); + return client.GetSubscriptionOperations(resourceId.SubscriptionId).GetResourceGroupOperations(resourceId.ResourceGroupName).GetVirtualMachineOperations(resourceId.Name); } } } diff --git a/sdk/resourcemanager/Proto.Client/compute/Extensions/SubscriptionExtensions.cs b/sdk/resourcemanager/Proto.Client/compute/Extensions/SubscriptionExtensions.cs index 8a9c3d619395..d9fb321f546c 100644 --- a/sdk/resourcemanager/Proto.Client/compute/Extensions/SubscriptionExtensions.cs +++ b/sdk/resourcemanager/Proto.Client/compute/Extensions/SubscriptionExtensions.cs @@ -32,7 +32,7 @@ private static ComputeManagementClient GetComputeClient(SubscriptionOperations s { return new ComputeManagementClient( subscription.BaseUri, - subscription.Id.Subscription, + subscription.Id.SubscriptionId, subscription.Credential, subscription.ClientOptions.Convert()); } diff --git a/sdk/resourcemanager/Proto.Client/compute/Placeholder/AvailabilitySetData.cs b/sdk/resourcemanager/Proto.Client/compute/Placeholder/AvailabilitySetData.cs index 57b1f66a3602..63e6354d9f5a 100644 --- a/sdk/resourcemanager/Proto.Client/compute/Placeholder/AvailabilitySetData.cs +++ b/sdk/resourcemanager/Proto.Client/compute/Placeholder/AvailabilitySetData.cs @@ -8,7 +8,7 @@ namespace Proto.Compute /// /// A class representing the availability set data model. /// - public class AvailabilitySetData : TrackedResource + public class AvailabilitySetData : TrackedResource { /// /// Gets the resource type definition for an availability set. diff --git a/sdk/resourcemanager/Proto.Client/compute/Placeholder/VirtualMachineData.cs b/sdk/resourcemanager/Proto.Client/compute/Placeholder/VirtualMachineData.cs index 65f46a4961fc..1f047c7a58e3 100644 --- a/sdk/resourcemanager/Proto.Client/compute/Placeholder/VirtualMachineData.cs +++ b/sdk/resourcemanager/Proto.Client/compute/Placeholder/VirtualMachineData.cs @@ -8,7 +8,7 @@ namespace Proto.Compute /// /// A class representing the VirtualMachine data model. /// - public class VirtualMachineData : TrackedResource + public class VirtualMachineData : TrackedResource { /// /// Initializes a new instance of the class. @@ -136,12 +136,12 @@ public ResourceIdentity Identity private ResourceIdentity VmIdentityToIdentity(VirtualMachineIdentity vmIdentity) { SystemAssignedIdentity systemAssignedIdentity = new SystemAssignedIdentity(new Guid(vmIdentity.TenantId), new Guid(vmIdentity.PrincipalId)); - var userAssignedIdentities = new Dictionary(); + var userAssignedIdentities = new Dictionary(); if (vmIdentity.UserAssignedIdentities != null) { foreach (var entry in vmIdentity.UserAssignedIdentities) { - ResourceIdentifier resourceId = new ResourceIdentifier(entry.Key); + var resourceId = new ResourceGroupResourceIdentifier(entry.Key); var userAssignedIdentity = new UserAssignedIdentity(new Guid(entry.Value.ClientId), new Guid(entry.Value.PrincipalId)); userAssignedIdentities[resourceId] = userAssignedIdentity; } diff --git a/sdk/resourcemanager/Proto.Client/compute/VirtualMachineContainer.cs b/sdk/resourcemanager/Proto.Client/compute/VirtualMachineContainer.cs index 249d9a077064..47b755470a5f 100644 --- a/sdk/resourcemanager/Proto.Client/compute/VirtualMachineContainer.cs +++ b/sdk/resourcemanager/Proto.Client/compute/VirtualMachineContainer.cs @@ -13,7 +13,7 @@ namespace Proto.Compute /// /// A class representing collection of VirtualMachine and their operations over a ResourceGroup. /// - public class VirtualMachineContainer : ResourceContainerBase + public class VirtualMachineContainer : ResourceContainerBase { /// /// Initializes a new instance of the class. @@ -24,9 +24,14 @@ internal VirtualMachineContainer(ResourceGroupOperations resourceGroup) { } + /// + /// Typed Resource Identifier for the container. + /// + public new ResourceGroupResourceIdentifier Id => base.Id as ResourceGroupResourceIdentifier; + private VirtualMachinesOperations Operations => new ComputeManagementClient( BaseUri, - Id.Subscription, + Id.SubscriptionId, Credential, ClientOptions.Convert()).VirtualMachines; @@ -44,7 +49,7 @@ internal VirtualMachineContainer(ResourceGroupOperations resourceGroup) /// A response with the operation for this resource. public override ArmResponse CreateOrUpdate(string name, VirtualMachineData resourceDetails, CancellationToken cancellationToken = default) { - var operation = Operations.StartCreateOrUpdate(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken); + var operation = Operations.StartCreateOrUpdate(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken); return new PhArmResponse( operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), v => new VirtualMachine(Parent, new VirtualMachineData(v))); @@ -59,7 +64,7 @@ public override ArmResponse CreateOrUpdate(string name, VirtualM /// A that on completion returns a response with the operation for this resource. public async override Task> CreateOrUpdateAsync(string name, VirtualMachineData resourceDetails, CancellationToken cancellationToken = default) { - var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false); + var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false); return new PhArmResponse( await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), v => new VirtualMachine(Parent, new VirtualMachineData(v))); @@ -78,7 +83,7 @@ await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), public override ArmOperation StartCreateOrUpdate(string name, VirtualMachineData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - Operations.StartCreateOrUpdate(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken), + Operations.StartCreateOrUpdate(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken), v => new VirtualMachine(Parent, new VirtualMachineData(v))); } @@ -95,7 +100,7 @@ public override ArmOperation StartCreateOrUpdate(string name, Vi public async override Task> StartCreateOrUpdateAsync(string name, VirtualMachineData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false), + await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false), v => new VirtualMachine(Parent, new VirtualMachineData(v))); } @@ -111,7 +116,7 @@ await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetail /// Object used to create a . public VirtualMachineModelBuilder Construct(string hostName, string adminUser, string adminPassword, ResourceIdentifier networkInterfaceId, ResourceIdentifier availabilitySetId, LocationData location = null) { - var parent = GetParentResource(); + var parent = GetParentResource(); var vm = new Azure.ResourceManager.Compute.Models.VirtualMachine(location ?? parent.Data.Location) { NetworkProfile = new NetworkProfile(), @@ -225,14 +230,14 @@ public AsyncPageable ListAsync(string nameFilter, int? top = nul /// public override ArmResponse Get(string virtualMachineName, CancellationToken cancellationToken = default) { - return new PhArmResponse(Operations.Get(Id.ResourceGroup, virtualMachineName, cancellationToken), + return new PhArmResponse(Operations.Get(Id.ResourceGroupName, virtualMachineName, cancellationToken), v => new VirtualMachine(Parent, new VirtualMachineData(v))); } /// public override async Task> GetAsync(string virtualMachineName, CancellationToken cancellationToken = default) { - return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroup, virtualMachineName, cancellationToken), + return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroupName, virtualMachineName, cancellationToken), v => new VirtualMachine(Parent, new VirtualMachineData(v))); } } diff --git a/sdk/resourcemanager/Proto.Client/compute/VirtualMachineOperations.cs b/sdk/resourcemanager/Proto.Client/compute/VirtualMachineOperations.cs index a0e07d582341..503bb80275f1 100644 --- a/sdk/resourcemanager/Proto.Client/compute/VirtualMachineOperations.cs +++ b/sdk/resourcemanager/Proto.Client/compute/VirtualMachineOperations.cs @@ -12,7 +12,7 @@ namespace Proto.Compute /// /// A class representing the operations that can be performed over a specific VirtualMachine. /// - public class VirtualMachineOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource + public class VirtualMachineOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource { /// /// Initializes a new instance of the class. @@ -29,7 +29,7 @@ internal VirtualMachineOperations(GenericResourceOperations genericOperations) /// The client parameters to use in these operations. /// The identifier of the resource that is the target of operations. internal VirtualMachineOperations(ResourceGroupOperations resourceGroup, string vmName) - : base(resourceGroup, $"{resourceGroup.Id}/providers/Microsoft.Compute/virtualMachines/{vmName}") + : base(resourceGroup, resourceGroup.Id.AppendProviderResource(ResourceType.Namespace, ResourceType.Type, vmName)) { } @@ -38,7 +38,7 @@ internal VirtualMachineOperations(ResourceGroupOperations resourceGroup, string /// /// The client parameters to use in these operations. /// The identifier of the resource that is the target of operations. - protected VirtualMachineOperations(ResourceOperationsBase operation, ResourceIdentifier id) + protected VirtualMachineOperations(ResourceOperationsBase operation, ResourceGroupResourceIdentifier id) : base(operation, id) { } @@ -55,7 +55,7 @@ protected VirtualMachineOperations(ResourceOperationsBase operation, ResourceIde private VirtualMachinesOperations Operations => new ComputeManagementClient( BaseUri, - Id.Subscription, + Id.SubscriptionId, Credential, ClientOptions.Convert()).VirtualMachines; @@ -72,25 +72,25 @@ public static VirtualMachineOperations FromGeneric(GenericResourceOperations gen /// public ArmResponse Delete(CancellationToken cancellationToken = default) { - return new ArmResponse(Operations.StartDelete(Id.ResourceGroup, Id.Name, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); + return new ArmResponse(Operations.StartDelete(Id.ResourceGroupName, Id.Name, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } /// public async Task> DeleteAsync(CancellationToken cancellationToken = default) { - return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); + return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } /// public ArmOperation StartDelete(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// public async Task> StartDeleteAsync(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)); } #region PowerOn @@ -101,7 +101,7 @@ public async Task> StartDeleteAsync(CancellationToken can /// A response with the operation for this resource. public ArmResponse PowerOn(CancellationToken cancellationToken = default) { - var operation = Operations.StartStart(Id.ResourceGroup, Id.Name, cancellationToken); + var operation = Operations.StartStart(Id.ResourceGroupName, Id.Name, cancellationToken); return new ArmResponse(operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } @@ -112,7 +112,7 @@ public ArmResponse PowerOn(CancellationToken cancellationToken = defau /// A that on completion returns a response with the operation for this resource. public async Task> PowerOnAsync(CancellationToken cancellationToken = default) { - var operation = await Operations.StartStartAsync(Id.ResourceGroup, Id.Name, cancellationToken).ConfigureAwait(false); + var operation = await Operations.StartStartAsync(Id.ResourceGroupName, Id.Name, cancellationToken).ConfigureAwait(false); return new ArmResponse(await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false)); } @@ -123,7 +123,7 @@ public async Task> PowerOnAsync(CancellationToken cancella /// An that allows polling for completion of the operation. public ArmOperation StartPowerOn(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(Operations.StartStart(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(Operations.StartStart(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// @@ -133,7 +133,7 @@ public ArmOperation StartPowerOn(CancellationToken cancellationToken = /// A that on completion returns an that allows polling for completion of the operation. public async Task> StartPowerOnAsync(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(await Operations.StartStartAsync(Id.ResourceGroup, Id.Name, cancellationToken).ConfigureAwait(false)); + return new ArmVoidOperation(await Operations.StartStartAsync(Id.ResourceGroupName, Id.Name, cancellationToken).ConfigureAwait(false)); } #endregion @@ -146,7 +146,7 @@ public async Task> StartPowerOnAsync(CancellationToken ca /// A response with the operation for this resource. public ArmResponse PowerOff(bool? skipShutdown = null, CancellationToken cancellationToken = default) { - var operation = Operations.StartPowerOff(Id.ResourceGroup, Id.Name, skipShutdown, cancellationToken); + var operation = Operations.StartPowerOff(Id.ResourceGroupName, Id.Name, skipShutdown, cancellationToken); return new ArmResponse(operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } @@ -158,7 +158,7 @@ public ArmResponse PowerOff(bool? skipShutdown = null, CancellationTok /// A that on completion returns a response with the operation for this resource. public async Task> PowerOffAsync(bool? skipShutdown = null, CancellationToken cancellationToken = default) { - var operation = await Operations.StartPowerOffAsync(Id.ResourceGroup, Id.Name, skipShutdown, cancellationToken).ConfigureAwait(false); + var operation = await Operations.StartPowerOffAsync(Id.ResourceGroupName, Id.Name, skipShutdown, cancellationToken).ConfigureAwait(false); return new ArmResponse(await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false)); } @@ -170,7 +170,7 @@ public async Task> PowerOffAsync(bool? skipShutdown = null /// An that allows polling for completion of the operation. public ArmOperation StartPowerOff(bool? skipShutdown = null, CancellationToken cancellationToken = default) { - return new ArmVoidOperation(Operations.StartPowerOff(Id.ResourceGroup, Id.Name, skipShutdown, cancellationToken)); + return new ArmVoidOperation(Operations.StartPowerOff(Id.ResourceGroupName, Id.Name, skipShutdown, cancellationToken)); } /// @@ -181,7 +181,7 @@ public ArmOperation StartPowerOff(bool? skipShutdown = null, Cancellat /// A that on completion returns an that allows polling for completion of the operation. public async Task> StartPowerOffAsync(bool? skipShutdown = null, CancellationToken cancellationToken = default) { - return new ArmVoidOperation(await Operations.StartPowerOffAsync(Id.ResourceGroup, Id.Name, skipShutdown, cancellationToken).ConfigureAwait(false)); + return new ArmVoidOperation(await Operations.StartPowerOffAsync(Id.ResourceGroupName, Id.Name, skipShutdown, cancellationToken).ConfigureAwait(false)); } #endregion @@ -189,7 +189,7 @@ public async Task> StartPowerOffAsync(bool? skipShutdown public override ArmResponse Get(CancellationToken cancellationToken = default) { return new PhArmResponse( - Operations.Get(Id.ResourceGroup, Id.Name, cancellationToken), + Operations.Get(Id.ResourceGroupName, Id.Name, cancellationToken), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -197,7 +197,7 @@ public override ArmResponse Get(CancellationToken cancellationTo public override async Task> GetAsync(CancellationToken cancellationToken = default) { return new PhArmResponse( - await Operations.GetAsync(Id.ResourceGroup, Id.Name, cancellationToken), + await Operations.GetAsync(Id.ResourceGroupName, Id.Name, cancellationToken), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -209,7 +209,7 @@ await Operations.GetAsync(Id.ResourceGroup, Id.Name, cancellationToken), public ArmOperation StartUpdate(VirtualMachineUpdate patchable, CancellationToken cancellationToken = default) { return new PhArmOperation( - Operations.StartUpdate(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.StartUpdate(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -222,7 +222,7 @@ public ArmOperation StartUpdate(VirtualMachineUpdate patchable, public async Task> StartUpdateAsync(VirtualMachineUpdate patchable, CancellationToken cancellationToken = default) { return new PhArmOperation( - await Operations.StartUpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.StartUpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -235,7 +235,7 @@ public ArmResponse AddTag(string key, string value, Cancellation patchable.Tags[key] = value; return new PhArmResponse( - Operations.StartUpdate(Id.ResourceGroup, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), + Operations.StartUpdate(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -248,7 +248,7 @@ public async Task> AddTagAsync(string key, string va patchable.Tags[key] = value; return new PhArmResponse( - await Operations.StartUpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(), + await Operations.StartUpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -261,7 +261,7 @@ public ArmOperation StartAddTag(string key, string value, Cancel patchable.Tags[key] = value; return new PhArmOperation( - Operations.StartUpdate(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.StartUpdate(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -274,7 +274,7 @@ public async Task> StartAddTagAsync(string key, str patchable.Tags[key] = value; return new PhArmOperation( - await Operations.StartUpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.StartUpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -285,7 +285,7 @@ public ArmResponse SetTags(IDictionary tags, Can patchable.Tags.ReplaceWith(tags); return new PhArmResponse( - Operations.StartUpdate(Id.ResourceGroup, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), + Operations.StartUpdate(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -296,7 +296,7 @@ public async Task> SetTagsAsync(IDictionary( - await Operations.StartUpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(cancellationToken), + await Operations.StartUpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(cancellationToken), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -307,7 +307,7 @@ public ArmOperation StartSetTags(IDictionary tag patchable.Tags.ReplaceWith(tags); return new PhArmOperation( - Operations.StartUpdate(Id.ResourceGroup, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), + Operations.StartUpdate(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -318,7 +318,7 @@ public async Task> StartSetTagsAsync(IDictionary( - await Operations.StartUpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(cancellationToken), + await Operations.StartUpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(cancellationToken), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -331,7 +331,7 @@ public ArmResponse RemoveTag(string key, CancellationToken cance patchable.Tags.Remove(key); return new PhArmResponse( - Operations.StartUpdate(Id.ResourceGroup, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), + Operations.StartUpdate(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -344,7 +344,7 @@ public async Task> RemoveTagAsync(string key, Cancel patchable.Tags.Remove(key); return new PhArmResponse( - await Operations.StartUpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(cancellationToken), + await Operations.StartUpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(cancellationToken), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -357,7 +357,7 @@ public ArmOperation StartRemoveTag(string key, CancellationToken patchable.Tags.Remove(key); return new PhArmOperation( - Operations.StartUpdate(Id.ResourceGroup, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), + Operations.StartUpdate(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), v => new VirtualMachine(this, new VirtualMachineData(v))); } @@ -370,7 +370,7 @@ public async Task> StartRemoveTagAsync(string key, patchable.Tags.Remove(key); return new PhArmOperation( - await Operations.StartUpdateAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(cancellationToken), + await Operations.StartUpdateAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken).Result.WaitForCompletionAsync(cancellationToken), v => new VirtualMachine(this, new VirtualMachineData(v))); } diff --git a/sdk/resourcemanager/Proto.Client/network/Extensions/ArmClientExtensions.cs b/sdk/resourcemanager/Proto.Client/network/Extensions/ArmClientExtensions.cs index 1b5103d57f99..c1474cc3b628 100644 --- a/sdk/resourcemanager/Proto.Client/network/Extensions/ArmClientExtensions.cs +++ b/sdk/resourcemanager/Proto.Client/network/Extensions/ArmClientExtensions.cs @@ -17,15 +17,15 @@ public static class ArmClientExtensions /// Returns an object representing the operations that can be performed over a specific . /// ResourceIdentifier provided is not for a NetworkInterfaceOperations. /// ResourceIdentifier cannot be null. - public static NetworkInterfaceOperations GetNetworkInterfaceOperations(this AzureResourceManagerClient client, ResourceIdentifier resourceId) + public static NetworkInterfaceOperations GetNetworkInterfaceOperations(this AzureResourceManagerClient client, ResourceGroupResourceIdentifier resourceId) { if (resourceId is null) throw new ArgumentNullException(nameof(resourceId)); - if (resourceId.Type != NetworkInterfaceOperations.ResourceType) - throw new ArgumentException($"{nameof(resourceId.Type)} provided is not for a NetworkInterface.", nameof(resourceId.Type)); + if (resourceId.ResourceType != NetworkInterfaceOperations.ResourceType) + throw new ArgumentException($"{nameof(resourceId.ResourceType)} provided is not for a NetworkInterface.", nameof(resourceId.ResourceType)); - var subOps = client.GetSubscriptionOperations(resourceId.Subscription); - var rgOps = subOps.GetResourceGroupOperations(resourceId.ResourceGroup); + var subOps = client.GetSubscriptionOperations(resourceId.SubscriptionId); + var rgOps = subOps.GetResourceGroupOperations(resourceId.ResourceGroupName); return rgOps.GetNetworkInterfaceOperations(resourceId.Name); } @@ -37,15 +37,15 @@ public static NetworkInterfaceOperations GetNetworkInterfaceOperations(this Azur /// Returns an object representing the operations that can be performed over a specific . /// ResourceIdentifier provided is not for a NetworkSecurityGroup. /// ResourceIdentifier cannot be null. - public static NetworkSecurityGroupOperations GetNetworkSecurityGroupOperations(this AzureResourceManagerClient client, ResourceIdentifier resourceId) + public static NetworkSecurityGroupOperations GetNetworkSecurityGroupOperations(this AzureResourceManagerClient client, ResourceGroupResourceIdentifier resourceId) { if (resourceId is null) throw new ArgumentNullException(nameof(resourceId)); - if (resourceId.Type != NetworkSecurityGroupOperations.ResourceType) - throw new ArgumentException($"{nameof(resourceId.Type)} provided is not for a NetworkSecurityGroup.", nameof(resourceId.Type)); + if (resourceId.ResourceType != NetworkSecurityGroupOperations.ResourceType) + throw new ArgumentException($"{nameof(resourceId.ResourceType)} provided is not for a NetworkSecurityGroup.", nameof(resourceId.ResourceType)); - var subOps = client.GetSubscriptionOperations(resourceId.Subscription); - var rgOps = subOps.GetResourceGroupOperations(resourceId.ResourceGroup); + var subOps = client.GetSubscriptionOperations(resourceId.SubscriptionId); + var rgOps = subOps.GetResourceGroupOperations(resourceId.ResourceGroupName); return rgOps.GetNetworkSecurityGroupOperations(resourceId.Name); } @@ -57,15 +57,15 @@ public static NetworkSecurityGroupOperations GetNetworkSecurityGroupOperations(t /// Returns an object representing the operations that can be performed over a specific . /// ResourceIdentifier provided is not for a PublicIpAddress. /// ResourceIdentifier cannot be null. - public static PublicIpAddressOperations GetPublicIpAddressOperations(this AzureResourceManagerClient client, ResourceIdentifier resourceId) + public static PublicIpAddressOperations GetPublicIpAddressOperations(this AzureResourceManagerClient client, ResourceGroupResourceIdentifier resourceId) { if (resourceId is null) throw new ArgumentNullException(nameof(resourceId)); - if (resourceId.Type != PublicIpAddressOperations.ResourceType) - throw new ArgumentException($"{nameof(resourceId.Type)} provided is not for a PublicIpAddress.", nameof(resourceId.Type)); + if (resourceId.ResourceType != PublicIpAddressOperations.ResourceType) + throw new ArgumentException($"{nameof(resourceId.ResourceType)} provided is not for a PublicIpAddress.", nameof(resourceId.ResourceType)); - var subOps = client.GetSubscriptionOperations(resourceId.Subscription); - var rgOps = subOps.GetResourceGroupOperations(resourceId.ResourceGroup); + var subOps = client.GetSubscriptionOperations(resourceId.SubscriptionId); + var rgOps = subOps.GetResourceGroupOperations(resourceId.ResourceGroupName); return rgOps.GetPublicIpAddressOperations(resourceId.Name); } @@ -77,14 +77,14 @@ public static PublicIpAddressOperations GetPublicIpAddressOperations(this AzureR /// Returns an object representing the operations that can be performed over a specific . /// ResourceIdentifier provided is not for a Subnet. /// ResourceIdentifier cannot be null. - public static SubnetOperations GetSubnetOperations(this AzureResourceManagerClient client, ResourceIdentifier resourceId) + public static SubnetOperations GetSubnetOperations(this AzureResourceManagerClient client, ResourceGroupResourceIdentifier resourceId) { if (resourceId is null) throw new ArgumentNullException(nameof(resourceId)); - if (resourceId.Type != SubnetOperations.ResourceType) - throw new ArgumentException($"{nameof(resourceId.Type)} provided is not for a Subnet.", nameof(resourceId.Type)); - var subOps = client.GetSubscriptionOperations(resourceId.Subscription); - var rgOps = subOps.GetResourceGroupOperations(resourceId.ResourceGroup); + if (resourceId.ResourceType != SubnetOperations.ResourceType) + throw new ArgumentException($"{nameof(resourceId.ResourceType)} provided is not for a Subnet.", nameof(resourceId.ResourceType)); + var subOps = client.GetSubscriptionOperations(resourceId.SubscriptionId); + var rgOps = subOps.GetResourceGroupOperations(resourceId.ResourceGroupName); var vnetOps = rgOps.GetVirtualNetworkOperations(resourceId.Parent.Name); return vnetOps.GetSubnetOperations(resourceId.Name); } @@ -97,15 +97,15 @@ public static SubnetOperations GetSubnetOperations(this AzureResourceManagerClie /// Returns an object representing the operations that can be performed over a specific . /// ResourceIdentifier provided is not for a VirtualNetwork. /// ResourceIdentifier cannot be null. - public static VirtualNetworkOperations GetVirtualNetworkOperations(this AzureResourceManagerClient client, ResourceIdentifier resourceId) + public static VirtualNetworkOperations GetVirtualNetworkOperations(this AzureResourceManagerClient client, ResourceGroupResourceIdentifier resourceId) { if (resourceId is null) throw new ArgumentNullException(nameof(resourceId)); - if (resourceId.Type != VirtualNetworkOperations.ResourceType) - throw new ArgumentException($"{nameof(resourceId.Type)} provided is not for a VirtualNetwork.", nameof(resourceId.Type)); + if (resourceId.ResourceType != VirtualNetworkOperations.ResourceType) + throw new ArgumentException($"{nameof(resourceId.ResourceType)} provided is not for a VirtualNetwork.", nameof(resourceId.ResourceType)); - var subOps = client.GetSubscriptionOperations(resourceId.Subscription); - var rgOps = subOps.GetResourceGroupOperations(resourceId.ResourceGroup); + var subOps = client.GetSubscriptionOperations(resourceId.SubscriptionId); + var rgOps = subOps.GetResourceGroupOperations(resourceId.ResourceGroupName); return rgOps.GetVirtualNetworkOperations(resourceId.Parent.Name); } } diff --git a/sdk/resourcemanager/Proto.Client/network/Extensions/SubscriptionExtensions.cs b/sdk/resourcemanager/Proto.Client/network/Extensions/SubscriptionExtensions.cs index 84e66631beea..8846825348a8 100644 --- a/sdk/resourcemanager/Proto.Client/network/Extensions/SubscriptionExtensions.cs +++ b/sdk/resourcemanager/Proto.Client/network/Extensions/SubscriptionExtensions.cs @@ -18,7 +18,7 @@ public static class SubscriptionExtensions private static NetworkManagementClient GetNetworkClient(SubscriptionOperations subscription) { return new NetworkManagementClient( - subscription.Id.Subscription, + subscription.Id.SubscriptionId, subscription.BaseUri, subscription.Credential, subscription.ClientOptions.Convert()); diff --git a/sdk/resourcemanager/Proto.Client/network/NetworkInterfaceContainer.cs b/sdk/resourcemanager/Proto.Client/network/NetworkInterfaceContainer.cs index 8720586116fe..8ca3a7a84a54 100644 --- a/sdk/resourcemanager/Proto.Client/network/NetworkInterfaceContainer.cs +++ b/sdk/resourcemanager/Proto.Client/network/NetworkInterfaceContainer.cs @@ -16,7 +16,7 @@ namespace Proto.Network /// /// A class representing collection of and their operations over a . /// - public class NetworkInterfaceContainer : ResourceContainerBase + public class NetworkInterfaceContainer : ResourceContainerBase { internal NetworkInterfaceContainer(ResourceGroupOperations resourceGroup) : base(resourceGroup) @@ -24,18 +24,23 @@ internal NetworkInterfaceContainer(ResourceGroupOperations resourceGroup) } internal NetworkInterfacesOperations Operations => new NetworkManagementClient( - Id.Subscription, + Id.SubscriptionId, BaseUri, Credential, ClientOptions.Convert()).NetworkInterfaces; /// + /// + /// Typed Resource Identifier for the container. + /// + public new ResourceGroupResourceIdentifier Id => base.Id as ResourceGroupResourceIdentifier; + protected override ResourceType ValidResourceType => ResourceGroupOperations.ResourceType; /// public override ArmResponse CreateOrUpdate(string name, NetworkInterfaceData resourceDetails, CancellationToken cancellationToken = default) { - var operation = Operations.StartCreateOrUpdate(Id.ResourceGroup, name, resourceDetails, cancellationToken); + var operation = Operations.StartCreateOrUpdate(Id.ResourceGroupName, name, resourceDetails, cancellationToken); return new PhArmResponse( operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), n => new NetworkInterface(Parent, new NetworkInterfaceData(n))); @@ -44,7 +49,7 @@ public override ArmResponse CreateOrUpdate(string name, Networ /// public async override Task> CreateOrUpdateAsync(string name, NetworkInterfaceData resourceDetails, CancellationToken cancellationToken = default) { - var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails, cancellationToken).ConfigureAwait(false); + var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails, cancellationToken).ConfigureAwait(false); return new PhArmResponse( await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), n => new NetworkInterface(Parent, new NetworkInterfaceData(n))); @@ -54,7 +59,7 @@ await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), public override ArmOperation StartCreateOrUpdate(string name, NetworkInterfaceData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - Operations.StartCreateOrUpdate(Id.ResourceGroup, name, resourceDetails, cancellationToken), + Operations.StartCreateOrUpdate(Id.ResourceGroupName, name, resourceDetails, cancellationToken), n => new NetworkInterface(Parent, new NetworkInterfaceData(n))); } @@ -62,7 +67,7 @@ public override ArmOperation StartCreateOrUpdate(string name, public async override Task> StartCreateOrUpdateAsync(string name, NetworkInterfaceData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails, cancellationToken).ConfigureAwait(false), + await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails, cancellationToken).ConfigureAwait(false), n => new NetworkInterface(Parent, new NetworkInterfaceData(n))); } @@ -73,9 +78,9 @@ await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetail /// The resource identifier of the subnet attached to this . /// The that will contain the . /// An object used to create a . - public ArmBuilder Construct(string subnetId, PublicIPAddressData ip = default, LocationData location = null) + public ArmBuilder Construct(string subnetId, PublicIPAddressData ip = default, LocationData location = null) { - var parent = GetParentResource(); + var parent = GetParentResource(); var nic = new Azure.ResourceManager.Network.Models.NetworkInterface() { Location = location ?? parent.Data.Location, @@ -92,7 +97,7 @@ public ArmBuilder Construct(string subne if (ip != null) nic.IpConfigurations[0].PublicIPAddress = new PublicIPAddress() { Id = ip.Id }; - return new ArmBuilder(this, new NetworkInterfaceData(nic)); + return new ArmBuilder(this, new NetworkInterfaceData(nic)); } /// @@ -191,7 +196,7 @@ public AsyncPageable ListAsync(string nameFilter, int? top = n public override ArmResponse Get(string networkInterfaceName, CancellationToken cancellationToken = default) { return new PhArmResponse( - Operations.Get(Id.ResourceGroup, networkInterfaceName, cancellationToken: cancellationToken), + Operations.Get(Id.ResourceGroupName, networkInterfaceName, cancellationToken: cancellationToken), g => new NetworkInterface(Parent, new NetworkInterfaceData(g))); } @@ -199,7 +204,7 @@ public override ArmResponse Get(string networkInterfaceName, C public override async Task> GetAsync(string networkInterfaceName, CancellationToken cancellationToken = default) { return new PhArmResponse( - await Operations.GetAsync(Id.ResourceGroup, networkInterfaceName, null, cancellationToken), + await Operations.GetAsync(Id.ResourceGroupName, networkInterfaceName, null, cancellationToken), g => new NetworkInterface(Parent, new NetworkInterfaceData(g))); } } diff --git a/sdk/resourcemanager/Proto.Client/network/NetworkInterfaceOperations.cs b/sdk/resourcemanager/Proto.Client/network/NetworkInterfaceOperations.cs index ca740c0ae7a6..e5dca8855c13 100644 --- a/sdk/resourcemanager/Proto.Client/network/NetworkInterfaceOperations.cs +++ b/sdk/resourcemanager/Proto.Client/network/NetworkInterfaceOperations.cs @@ -12,7 +12,7 @@ namespace Proto.Network /// /// A class representing the operations that can be pefroemd over a specific . /// - public class NetworkInterfaceOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource + public class NetworkInterfaceOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource { internal NetworkInterfaceOperations(GenericResourceOperations genericOperations) : base(genericOperations) @@ -20,7 +20,7 @@ internal NetworkInterfaceOperations(GenericResourceOperations genericOperations) } internal NetworkInterfaceOperations(ResourceGroupOperations resourceGroup, string nicName) - : base(resourceGroup, $"{resourceGroup.Id}/providers/Microsoft.Network/networkInterfaces/{nicName}") + : base(resourceGroup, resourceGroup.Id.AppendProviderResource( ResourceType.Namespace, ResourceType.Type, nicName)) { } @@ -29,7 +29,7 @@ internal NetworkInterfaceOperations(ResourceGroupOperations resourceGroup, strin /// /// The client parameters to use in these operations. /// The identifier of the resource that is the target of operations. - protected NetworkInterfaceOperations(ResourceOperationsBase options, ResourceIdentifier id) + protected NetworkInterfaceOperations(ResourceOperationsBase options, ResourceGroupResourceIdentifier id) : base(options, id) { } @@ -43,7 +43,7 @@ protected NetworkInterfaceOperations(ResourceOperationsBase options, ResourceIde protected override ResourceType ValidResourceType => ResourceType; internal NetworkInterfacesOperations Operations => new NetworkManagementClient( - Id.Subscription, + Id.SubscriptionId, BaseUri, Credential, ClientOptions.Convert()).NetworkInterfaces; @@ -51,34 +51,34 @@ protected NetworkInterfaceOperations(ResourceOperationsBase options, ResourceIde /// public ArmResponse Delete(CancellationToken cancellationToken = default) { - return new ArmResponse(Operations.StartDelete(Id.ResourceGroup, Id.Name, cancellationToken) + return new ArmResponse(Operations.StartDelete(Id.ResourceGroupName, Id.Name, cancellationToken) .WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } /// public async Task> DeleteAsync(CancellationToken cancellationToken = default) { - return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)) + return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)) .WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } /// public ArmOperation StartDelete(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// public async Task> StartDeleteAsync(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// public override ArmResponse Get(CancellationToken cancellationToken = default) { return new PhArmResponse( - Operations.Get(Id.ResourceGroup, Id.Name, cancellationToken: cancellationToken), + Operations.Get(Id.ResourceGroupName, Id.Name, cancellationToken: cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -86,7 +86,7 @@ public override ArmResponse Get(CancellationToken cancellation public async override Task> GetAsync(CancellationToken cancellationToken = default) { return new PhArmResponse( - await Operations.GetAsync(Id.ResourceGroup, Id.Name, null, cancellationToken), + await Operations.GetAsync(Id.ResourceGroupName, Id.Name, null, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -98,7 +98,7 @@ public ArmResponse AddTag(string key, string value, Cancellati patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; return new PhArmResponse( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -110,7 +110,7 @@ public async Task> AddTagAsync(string key, string patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; return new PhArmResponse( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -122,7 +122,7 @@ public ArmOperation StartAddTag(string key, string value, Canc patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; return new PhArmOperation( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -134,7 +134,7 @@ public async Task> StartAddTagAsync(string key, s patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; return new PhArmOperation( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -144,7 +144,7 @@ public ArmResponse SetTags(IDictionary tags, C var patchable = new TagsObject(); patchable.Tags.ReplaceWith(tags); return new PhArmResponse( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -154,7 +154,7 @@ public async Task> SetTagsAsync(IDictionary( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -164,7 +164,7 @@ public ArmOperation StartSetTags(IDictionary t var patchable = new TagsObject(); patchable.Tags.ReplaceWith(tags); return new PhArmOperation( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -174,7 +174,7 @@ public async Task> StartSetTagsAsync(IDictionary< var patchable = new TagsObject(); patchable.Tags.ReplaceWith(tags); return new PhArmOperation( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -186,7 +186,7 @@ public ArmResponse RemoveTag(string key, CancellationToken can patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); return new PhArmResponse( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -198,7 +198,7 @@ public async Task> RemoveTagAsync(string key, Canc patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); return new PhArmResponse( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -210,7 +210,7 @@ public ArmOperation StartRemoveTag(string key, CancellationTok patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); return new PhArmOperation( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } @@ -222,7 +222,7 @@ public async Task> StartRemoveTagAsync(string key patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); return new PhArmOperation( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkInterface(this, new NetworkInterfaceData(n))); } diff --git a/sdk/resourcemanager/Proto.Client/network/NetworkSecurityGroupContainer.cs b/sdk/resourcemanager/Proto.Client/network/NetworkSecurityGroupContainer.cs index 9ba6382d3c1d..3d6b63e4bfd8 100644 --- a/sdk/resourcemanager/Proto.Client/network/NetworkSecurityGroupContainer.cs +++ b/sdk/resourcemanager/Proto.Client/network/NetworkSecurityGroupContainer.cs @@ -15,7 +15,7 @@ namespace Proto.Network /// /// A class representing collection of NetworkSecurityGroup and their operations over a resource group. /// - public class NetworkSecurityGroupContainer : ResourceContainerBase + public class NetworkSecurityGroupContainer : ResourceContainerBase { /// /// Initializes a new instance of the class. @@ -38,10 +38,15 @@ internal NetworkSecurityGroupContainer(ResourceGroupOperations resourceGroup) /// /// Gets the valid resource type for network security groups. /// + /// + /// Typed Resource Identifier for the container. + /// + public new ResourceGroupResourceIdentifier Id => base.Id as ResourceGroupResourceIdentifier; + protected override ResourceType ValidResourceType => ResourceGroupOperations.ResourceType; private NetworkSecurityGroupsOperations Operations => new NetworkManagementClient( - Id.Subscription, + Id.SubscriptionId, BaseUri, Credential, ClientOptions.Convert()).NetworkSecurityGroups; @@ -49,7 +54,7 @@ internal NetworkSecurityGroupContainer(ResourceGroupOperations resourceGroup) /// public override ArmResponse CreateOrUpdate(string name, NetworkSecurityGroupData resourceDetails, CancellationToken cancellationToken = default) { - var operation = Operations.StartCreateOrUpdate(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken); + var operation = Operations.StartCreateOrUpdate(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken); return new PhArmResponse( operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), n => new NetworkSecurityGroup(Parent, new NetworkSecurityGroupData(n))); @@ -58,7 +63,7 @@ public override ArmResponse CreateOrUpdate(string name, Ne /// public override async Task> CreateOrUpdateAsync(string name, NetworkSecurityGroupData resourceDetails, CancellationToken cancellationToken = default) { - var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false); + var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false); return new PhArmResponse( await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), n => new NetworkSecurityGroup(Parent, new NetworkSecurityGroupData(n))); @@ -68,7 +73,7 @@ await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), public override ArmOperation StartCreateOrUpdate(string name, NetworkSecurityGroupData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - Operations.StartCreateOrUpdate(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken), + Operations.StartCreateOrUpdate(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken), n => new NetworkSecurityGroup(Parent, new NetworkSecurityGroupData(n))); } @@ -76,7 +81,7 @@ public override ArmOperation StartCreateOrUpdate(string na public override async Task> StartCreateOrUpdateAsync(string name, NetworkSecurityGroupData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false), + await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false), n => new NetworkSecurityGroup(Parent, new NetworkSecurityGroupData(n))); } @@ -86,9 +91,9 @@ await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetail /// The location to create the network security group. /// The location to create the network security group. /// Object used to create a . - public ArmBuilder Construct(LocationData locationData = null, params int[] openPorts) + public ArmBuilder Construct(LocationData locationData = null, params int[] openPorts) { - var parent = GetParentResource(); + var parent = GetParentResource(); var nsg = new Azure.ResourceManager.Network.Models.NetworkSecurityGroup { Location = locationData ?? parent.Data.Location @@ -112,7 +117,7 @@ public ArmBuilder Construct(Loca nsg.SecurityRules.Add(securityRule); } - return new ArmBuilder(this, new NetworkSecurityGroupData(nsg)); + return new ArmBuilder(this, new NetworkSecurityGroupData(nsg)); } /// @@ -120,9 +125,9 @@ public ArmBuilder Construct(Loca /// /// The location to create the network security group. /// Object used to create a . - public ArmBuilder Construct(params int[] openPorts) + public ArmBuilder Construct(params int[] openPorts) { - var parent = GetParentResource(); + var parent = GetParentResource(); var nsg = new Azure.ResourceManager.Network.Models.NetworkSecurityGroup { Location = parent.Data.Location, @@ -146,7 +151,7 @@ public ArmBuilder Construct(para nsg.SecurityRules.Add(securityRule); } - return new ArmBuilder(this, new NetworkSecurityGroupData(nsg)); + return new ArmBuilder(this, new NetworkSecurityGroupData(nsg)); } /// @@ -233,7 +238,7 @@ public AsyncPageable ListAsync(string nameFilter, int? top public override ArmResponse Get(string networkSecurityGroup, CancellationToken cancellationToken = default) { return new PhArmResponse( - Operations.Get(Id.ResourceGroup, networkSecurityGroup, cancellationToken: cancellationToken), + Operations.Get(Id.ResourceGroupName, networkSecurityGroup, cancellationToken: cancellationToken), g => new NetworkSecurityGroup(Parent, new NetworkSecurityGroupData(g))); } @@ -241,7 +246,7 @@ public override ArmResponse Get(string networkSecurityGrou public override async Task> GetAsync(string networkSecurityGroup, CancellationToken cancellationToken = default) { return new PhArmResponse( - await Operations.GetAsync(Id.ResourceGroup, networkSecurityGroup, null, cancellationToken), + await Operations.GetAsync(Id.ResourceGroupName, networkSecurityGroup, null, cancellationToken), g => new NetworkSecurityGroup(Parent, new NetworkSecurityGroupData(g))); } } diff --git a/sdk/resourcemanager/Proto.Client/network/NetworkSecurityGroupOperations.cs b/sdk/resourcemanager/Proto.Client/network/NetworkSecurityGroupOperations.cs index f646f6dc33be..a83e36b3edb7 100644 --- a/sdk/resourcemanager/Proto.Client/network/NetworkSecurityGroupOperations.cs +++ b/sdk/resourcemanager/Proto.Client/network/NetworkSecurityGroupOperations.cs @@ -16,7 +16,7 @@ namespace Proto.Network /// /// A class representing the operations that can be performed over a specific NetworkSecurityGroup. /// - public class NetworkSecurityGroupOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource + public class NetworkSecurityGroupOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource { /// /// Initializes a new instance of the class. @@ -33,7 +33,7 @@ internal NetworkSecurityGroupOperations(GenericResourceOperations genericOperati /// The client parameters to use in these operations. /// The network security group name. internal NetworkSecurityGroupOperations(ResourceGroupOperations resourceGroup, string nsgName) - : base(resourceGroup, $"{resourceGroup.Id}/providers/Microsoft.Network/networkSecurityGroups/{nsgName}") + : base(resourceGroup, resourceGroup.Id.AppendProviderResource(ResourceType.Namespace, ResourceType.Type, nsgName)) { } @@ -56,7 +56,7 @@ protected NetworkSecurityGroupOperations(ResourceOperationsBase operation, Resou public static readonly ResourceType ResourceType = "Microsoft.Network/networkSecurityGroups"; private NetworkSecurityGroupsOperations Operations => new NetworkManagementClient( - Id.Subscription, + Id.SubscriptionId, BaseUri, Credential, ClientOptions.Convert()).NetworkSecurityGroups; @@ -97,7 +97,7 @@ public ArmOperation UpdateRules(CancellationToken cancella } return new PhArmOperation( - Operations.StartCreateOrUpdate(Id.ResourceGroup, Id.Name, resource.Data), + Operations.StartCreateOrUpdate(Id.ResourceGroupName, Id.Name, resource.Data), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -105,7 +105,7 @@ public ArmOperation UpdateRules(CancellationToken cancella public override ArmResponse Get(CancellationToken cancellationToken = default) { return new PhArmResponse( - Operations.Get(Id.ResourceGroup, Id.Name, cancellationToken: cancellationToken), + Operations.Get(Id.ResourceGroupName, Id.Name, cancellationToken: cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -113,7 +113,7 @@ public override ArmResponse Get(CancellationToken cancella public override async Task> GetAsync(CancellationToken cancellationToken = default) { return new PhArmResponse( - await Operations.GetAsync(Id.ResourceGroup, Id.Name, null, cancellationToken), + await Operations.GetAsync(Id.ResourceGroupName, Id.Name, null, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -125,7 +125,7 @@ public ArmResponse AddTag(string key, string value, Cancel patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; return new PhArmResponse( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -137,7 +137,7 @@ public async Task> AddTagAsync(string key, str patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; return new PhArmResponse( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -149,7 +149,7 @@ public ArmOperation StartAddTag(string key, string value, patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; return new PhArmOperation( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -161,34 +161,34 @@ public async Task> StartAddTagAsync(string ke patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; return new PhArmOperation( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } /// public ArmResponse Delete(CancellationToken cancellationToken = default) { - return new ArmResponse(Operations.StartDelete(Id.ResourceGroup, Id.Name, cancellationToken) + return new ArmResponse(Operations.StartDelete(Id.ResourceGroupName, Id.Name, cancellationToken) .WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } /// public async Task> DeleteAsync(CancellationToken cancellationToken = default) { - return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)) + return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)) .WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } /// public ArmOperation StartDelete(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// public async Task> StartDeleteAsync(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// @@ -203,7 +203,7 @@ public ArmResponse SetTags(IDictionary tag var patchable = new TagsObject(); patchable.Tags.ReplaceWith(tags); return new PhArmResponse( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -213,7 +213,7 @@ public async Task> SetTagsAsync(IDictionary( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -223,7 +223,7 @@ public ArmOperation StartSetTags(IDictionary( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -233,7 +233,7 @@ public async Task> StartSetTagsAsync(IDiction var patchable = new TagsObject(); patchable.Tags.ReplaceWith(tags); return new PhArmOperation( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -245,7 +245,7 @@ public ArmResponse RemoveTag(string key, CancellationToken patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); return new PhArmResponse( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -257,7 +257,7 @@ public async Task> RemoveTagAsync(string key, patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); return new PhArmResponse( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -269,7 +269,7 @@ public ArmOperation StartRemoveTag(string key, Cancellatio patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); return new PhArmOperation( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } @@ -281,7 +281,7 @@ public async Task> StartRemoveTagAsync(string patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); return new PhArmOperation( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new NetworkSecurityGroup(this, new NetworkSecurityGroupData(n))); } diff --git a/sdk/resourcemanager/Proto.Client/network/Placeholder/NetworkInterfaceData.cs b/sdk/resourcemanager/Proto.Client/network/Placeholder/NetworkInterfaceData.cs index c69b4442041f..905d5f1d76d4 100644 --- a/sdk/resourcemanager/Proto.Client/network/Placeholder/NetworkInterfaceData.cs +++ b/sdk/resourcemanager/Proto.Client/network/Placeholder/NetworkInterfaceData.cs @@ -8,7 +8,7 @@ namespace Proto.Network /// /// A network interface in a resource group. /// - public class NetworkInterfaceData : TrackedResource + public class NetworkInterfaceData : TrackedResource { /// /// The ARM resource type for this . diff --git a/sdk/resourcemanager/Proto.Client/network/Placeholder/NetworkSecurityGroupData.cs b/sdk/resourcemanager/Proto.Client/network/Placeholder/NetworkSecurityGroupData.cs index bfb5dfadc68d..977cf87bdeab 100644 --- a/sdk/resourcemanager/Proto.Client/network/Placeholder/NetworkSecurityGroupData.cs +++ b/sdk/resourcemanager/Proto.Client/network/Placeholder/NetworkSecurityGroupData.cs @@ -11,7 +11,7 @@ namespace Proto.Network /// A class representing the NetworkSecurityGroup data model. /// public class NetworkSecurityGroupData : - TrackedResource + TrackedResource { /// /// Initializes a new instance of the class. diff --git a/sdk/resourcemanager/Proto.Client/network/Placeholder/PublicIPAddressData.cs b/sdk/resourcemanager/Proto.Client/network/Placeholder/PublicIPAddressData.cs index 84303c1f83fc..a8baefb4c860 100644 --- a/sdk/resourcemanager/Proto.Client/network/Placeholder/PublicIPAddressData.cs +++ b/sdk/resourcemanager/Proto.Client/network/Placeholder/PublicIPAddressData.cs @@ -11,7 +11,7 @@ namespace Proto.Network /// /// A class representing the public IP address data model. /// - public class PublicIPAddressData : TrackedResource + public class PublicIPAddressData : TrackedResource { /// /// Gets the resource type definition for a public IP address. diff --git a/sdk/resourcemanager/Proto.Client/network/Placeholder/SubnetData.cs b/sdk/resourcemanager/Proto.Client/network/Placeholder/SubnetData.cs index 66fec3350b71..2e919f7d53cd 100644 --- a/sdk/resourcemanager/Proto.Client/network/Placeholder/SubnetData.cs +++ b/sdk/resourcemanager/Proto.Client/network/Placeholder/SubnetData.cs @@ -7,7 +7,7 @@ namespace Proto.Network /// /// A class representing the subnet data model. /// - public class SubnetData : ProxyResource + public class SubnetData : ProxyResource { /// /// Initializes a new instance of the class. diff --git a/sdk/resourcemanager/Proto.Client/network/Placeholder/VirtualNetworkData.cs b/sdk/resourcemanager/Proto.Client/network/Placeholder/VirtualNetworkData.cs index 07e62b448ca9..eb7fa5bb41ba 100644 --- a/sdk/resourcemanager/Proto.Client/network/Placeholder/VirtualNetworkData.cs +++ b/sdk/resourcemanager/Proto.Client/network/Placeholder/VirtualNetworkData.cs @@ -8,7 +8,7 @@ namespace Proto.Network /// /// A class representing the virtual nerwork data model. /// - public class VirtualNetworkData : TrackedResource + public class VirtualNetworkData : TrackedResource { /// /// Gets the resource type definition for a virtual nerwork. diff --git a/sdk/resourcemanager/Proto.Client/network/PublicIpAddressContainer.cs b/sdk/resourcemanager/Proto.Client/network/PublicIpAddressContainer.cs index 2279254d3364..2d60fbde72b3 100644 --- a/sdk/resourcemanager/Proto.Client/network/PublicIpAddressContainer.cs +++ b/sdk/resourcemanager/Proto.Client/network/PublicIpAddressContainer.cs @@ -15,7 +15,7 @@ namespace Proto.Network /// /// A class representing collection of PublicIpAddress and their operations over a resource group. /// - public class PublicIpAddressContainer : ResourceContainerBase + public class PublicIpAddressContainer : ResourceContainerBase { /// /// Initializes a new instance of the class. @@ -26,13 +26,18 @@ internal PublicIpAddressContainer(ResourceGroupOperations resourceGroup) { } + /// + /// Typed Resource Identifier for the container. + /// + public new ResourceGroupResourceIdentifier Id => base.Id as ResourceGroupResourceIdentifier; + /// /// Gets the valid resource type for this resource. /// protected override ResourceType ValidResourceType => ResourceGroupOperations.ResourceType; private PublicIPAddressesOperations Operations => new NetworkManagementClient( - Id.Subscription, + Id.SubscriptionId, BaseUri, Credential, ClientOptions.Convert()).PublicIPAddresses; @@ -40,7 +45,7 @@ internal PublicIpAddressContainer(ResourceGroupOperations resourceGroup) /// public override ArmResponse CreateOrUpdate(string name, PublicIPAddressData resourceDetails, CancellationToken cancellationToken = default) { - var operation = Operations.StartCreateOrUpdate(Id.ResourceGroup, name, resourceDetails, cancellationToken); + var operation = Operations.StartCreateOrUpdate(Id.ResourceGroupName, name, resourceDetails, cancellationToken); return new PhArmResponse( operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), n => new PublicIpAddress(Parent, new PublicIPAddressData(n))); @@ -49,7 +54,7 @@ public override ArmResponse CreateOrUpdate(string name, PublicI /// public override async Task> CreateOrUpdateAsync(string name, PublicIPAddressData resourceDetails, CancellationToken cancellationToken = default) { - var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails, cancellationToken).ConfigureAwait(false); + var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails, cancellationToken).ConfigureAwait(false); return new PhArmResponse( await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), n => new PublicIpAddress(Parent, new PublicIPAddressData(n))); @@ -59,7 +64,7 @@ await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), public override ArmOperation StartCreateOrUpdate(string name, PublicIPAddressData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - Operations.StartCreateOrUpdate(Id.ResourceGroup, name, resourceDetails, cancellationToken), + Operations.StartCreateOrUpdate(Id.ResourceGroupName, name, resourceDetails, cancellationToken), n => new PublicIpAddress(Parent, new PublicIPAddressData(n))); } @@ -67,7 +72,7 @@ public override ArmOperation StartCreateOrUpdate(string name, P public override async Task> StartCreateOrUpdateAsync(string name, PublicIPAddressData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails, cancellationToken).ConfigureAwait(false), + await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails, cancellationToken).ConfigureAwait(false), n => new PublicIpAddress(Parent, new PublicIPAddressData(n))); } @@ -76,9 +81,9 @@ await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetail /// /// The location to create the network security group. /// Object used to create a . - public ArmBuilder Construct(LocationData location = null) + public ArmBuilder Construct(LocationData location = null) { - var parent = GetParentResource(); + var parent = GetParentResource(); var ipAddress = new PublicIPAddress() { PublicIPAddressVersion = IPVersion.IPv4.ToString(), @@ -86,7 +91,7 @@ public ArmBuilder Construct(LocationData l Location = location ?? parent.Data.Location, }; - return new ArmBuilder(this, new PublicIPAddressData(ipAddress)); + return new ArmBuilder(this, new PublicIPAddressData(ipAddress)); } /// @@ -176,13 +181,13 @@ private Func Convertor() /// public override ArmResponse Get(string publicIpAddressesName, CancellationToken cancellationToken = default) { - return new PhArmResponse(Operations.Get(Id.ResourceGroup, publicIpAddressesName, cancellationToken: cancellationToken), Convertor()); + return new PhArmResponse(Operations.Get(Id.ResourceGroupName, publicIpAddressesName, cancellationToken: cancellationToken), Convertor()); } /// public override async Task> GetAsync(string publicIpAddressesName, CancellationToken cancellationToken = default) { - return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroup, publicIpAddressesName, cancellationToken: cancellationToken), Convertor()); + return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroupName, publicIpAddressesName, cancellationToken: cancellationToken), Convertor()); } } } diff --git a/sdk/resourcemanager/Proto.Client/network/PublicIpAddressOperations.cs b/sdk/resourcemanager/Proto.Client/network/PublicIpAddressOperations.cs index 34a28479857f..318202b72867 100644 --- a/sdk/resourcemanager/Proto.Client/network/PublicIpAddressOperations.cs +++ b/sdk/resourcemanager/Proto.Client/network/PublicIpAddressOperations.cs @@ -15,7 +15,7 @@ namespace Proto.Network /// /// A class representing the operations that can be performed over a specific NetworkSecurityGroup. /// - public class PublicIpAddressOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource + public class PublicIpAddressOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource { /// /// Initializes a new instance of the class. @@ -32,7 +32,7 @@ internal PublicIpAddressOperations(GenericResourceOperations genericOperations) /// The client parameters to use in these operations. /// The public ip address name. internal PublicIpAddressOperations(ResourceGroupOperations resourceGroup, string publicIpName) - : base(resourceGroup, $"{resourceGroup.Id}/providers/Microsoft.Network/publicIpAddresses/{publicIpName}") + : base(resourceGroup, resourceGroup.Id.AppendProviderResource(ResourceType.Namespace, ResourceType.Type, publicIpName)) { } @@ -55,7 +55,7 @@ protected PublicIpAddressOperations(ResourceOperationsBase options, ResourceIden protected override ResourceType ValidResourceType => ResourceType; private PublicIPAddressesOperations Operations => new NetworkManagementClient( - Id.Subscription, + Id.SubscriptionId, BaseUri, Credential, ClientOptions.Convert()).PublicIPAddresses; @@ -63,40 +63,40 @@ protected PublicIpAddressOperations(ResourceOperationsBase options, ResourceIden /// public ArmResponse Delete(CancellationToken cancellationToken = default) { - return new ArmResponse(Operations.StartDelete(Id.ResourceGroup, Id.Name, cancellationToken) + return new ArmResponse(Operations.StartDelete(Id.ResourceGroupName, Id.Name, cancellationToken) .WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } /// public async Task> DeleteAsync(CancellationToken cancellationToken = default) { - return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)) + return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)) .WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } /// public ArmOperation StartDelete(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// public async Task> StartDeleteAsync(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// public override ArmResponse Get(CancellationToken cancellationToken = default) { - return new PhArmResponse(Operations.Get(Id.ResourceGroup, Id.Name, cancellationToken: cancellationToken), + return new PhArmResponse(Operations.Get(Id.ResourceGroupName, Id.Name, cancellationToken: cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } /// public override async Task> GetAsync(CancellationToken cancellationToken = default) { - return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroup, Id.Name, null, cancellationToken), + return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroupName, Id.Name, null, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } @@ -107,7 +107,7 @@ public ArmResponse AddTag(string key, string value, Cancellatio var patchable = new TagsObject(); patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; - return new PhArmResponse(Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + return new PhArmResponse(Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } @@ -118,7 +118,7 @@ public async Task> AddTagAsync(string key, string v var patchable = new TagsObject(); patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; - return new PhArmResponse(await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + return new PhArmResponse(await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } @@ -129,7 +129,7 @@ public ArmOperation StartAddTag(string key, string value, Cance var patchable = new TagsObject(); patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; - return new PhArmOperation(Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + return new PhArmOperation(Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } @@ -140,7 +140,7 @@ public async Task> StartAddTagAsync(string key, st var patchable = new TagsObject(); patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; - return new PhArmOperation(await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + return new PhArmOperation(await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } @@ -149,7 +149,7 @@ public ArmResponse SetTags(IDictionary tags, Ca { var patchable = new TagsObject(); patchable.Tags.ReplaceWith(tags); - return new PhArmResponse(Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + return new PhArmResponse(Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } @@ -158,7 +158,7 @@ public async Task> SetTagsAsync(IDictionary(await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + return new PhArmResponse(await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } @@ -167,7 +167,7 @@ public ArmOperation StartSetTags(IDictionary ta { var patchable = new TagsObject(); patchable.Tags.ReplaceWith(tags); - return new PhArmOperation(Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + return new PhArmOperation(Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } @@ -176,7 +176,7 @@ public async Task> StartSetTagsAsync(IDictionary(await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + return new PhArmOperation(await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } @@ -187,7 +187,7 @@ public ArmResponse RemoveTag(string key, CancellationToken canc var patchable = new TagsObject(); patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); - return new PhArmResponse(Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + return new PhArmResponse(Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } @@ -198,7 +198,7 @@ public async Task> RemoveTagAsync(string key, Cance var patchable = new TagsObject(); patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); - return new PhArmResponse(await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + return new PhArmResponse(await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } @@ -209,7 +209,7 @@ public ArmOperation StartRemoveTag(string key, CancellationToke var patchable = new TagsObject(); patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); - return new PhArmOperation(Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + return new PhArmOperation(Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } @@ -220,7 +220,7 @@ public async Task> StartRemoveTagAsync(string key, var patchable = new TagsObject(); patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); - return new PhArmOperation(await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + return new PhArmOperation(await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new PublicIpAddress(this, new PublicIPAddressData(n))); } diff --git a/sdk/resourcemanager/Proto.Client/network/SubnetBuilder.cs b/sdk/resourcemanager/Proto.Client/network/SubnetBuilder.cs index b1c130ede655..ecc79bc866e9 100644 --- a/sdk/resourcemanager/Proto.Client/network/SubnetBuilder.cs +++ b/sdk/resourcemanager/Proto.Client/network/SubnetBuilder.cs @@ -5,7 +5,7 @@ namespace Proto.Network /// /// A class representing a builder object to help create a subnet. /// - public class SubnetBuilder : ArmBuilder + public class SubnetBuilder : ArmBuilder { /// /// Initializes a new instance of the class. diff --git a/sdk/resourcemanager/Proto.Client/network/SubnetContainer.cs b/sdk/resourcemanager/Proto.Client/network/SubnetContainer.cs index f141d4a5dd71..874f8f5d1c63 100644 --- a/sdk/resourcemanager/Proto.Client/network/SubnetContainer.cs +++ b/sdk/resourcemanager/Proto.Client/network/SubnetContainer.cs @@ -10,7 +10,7 @@ namespace Proto.Network /// /// A class representing collection of Subnets and their operations over a VirtualNetwork. /// - public class SubnetContainer : ResourceContainerBase + public class SubnetContainer : ResourceContainerBase { /// /// Initializes a new instance of the class. @@ -21,11 +21,16 @@ internal SubnetContainer(VirtualNetworkOperations virtualNetwork) { } + /// + /// Typed Resource Identifier for the container. + /// + public new ResourceGroupResourceIdentifier Id => base.Id as ResourceGroupResourceIdentifier; + /// protected override ResourceType ValidResourceType => VirtualNetworkOperations.ResourceType; private SubnetsOperations Operations => new NetworkManagementClient( - Id.Subscription, + Id.SubscriptionId, BaseUri, Credential, ClientOptions.Convert()).Subnets; @@ -33,7 +38,7 @@ internal SubnetContainer(VirtualNetworkOperations virtualNetwork) /// public override ArmResponse CreateOrUpdate(string name, SubnetData resourceDetails, CancellationToken cancellationToken = default) { - var operation = Operations.StartCreateOrUpdate(Id.ResourceGroup, Id.Name, name, resourceDetails.Model, cancellationToken); + var operation = Operations.StartCreateOrUpdate(Id.ResourceGroupName, Id.Name, name, resourceDetails.Model, cancellationToken); return new PhArmResponse( operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), s => new Subnet(Parent, new SubnetData(s))); @@ -42,7 +47,7 @@ public override ArmResponse CreateOrUpdate(string name, SubnetData resou /// public override async Task> CreateOrUpdateAsync(string name, SubnetData resourceDetails, CancellationToken cancellationToken = default) { - var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, Id.Name, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false); + var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, Id.Name, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false); return new PhArmResponse( await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), s => new Subnet(Parent, new SubnetData(s))); @@ -52,7 +57,7 @@ await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), public override ArmOperation StartCreateOrUpdate(string name, SubnetData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - Operations.StartCreateOrUpdate(Id.ResourceGroup, Id.Name, name, resourceDetails.Model, cancellationToken), + Operations.StartCreateOrUpdate(Id.ResourceGroupName, Id.Name, name, resourceDetails.Model, cancellationToken), s => new Subnet(Parent, new SubnetData(s))); } @@ -60,7 +65,7 @@ public override ArmOperation StartCreateOrUpdate(string name, SubnetData public async override Task> StartCreateOrUpdateAsync(string name, SubnetData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, Id.Name, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false), + await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, Id.Name, name, resourceDetails.Model, cancellationToken).ConfigureAwait(false), s => new Subnet(Parent, new SubnetData(s))); } @@ -93,7 +98,7 @@ public SubnetBuilder Construct(string subnetCidr, NetworkSecurityGroupData group public Pageable List(CancellationToken cancellationToken = default) { return new PhWrappingPageable( - Operations.List(Id.ResourceGroup, Id.Name, cancellationToken), + Operations.List(Id.ResourceGroupName, Id.Name, cancellationToken), convertor()); } @@ -105,7 +110,7 @@ public Pageable List(CancellationToken cancellationToken = default) public AsyncPageable ListAsync(CancellationToken cancellationToken = default) { return new PhWrappingAsyncPageable( - Operations.ListAsync(Id.ResourceGroup, Id.Name, cancellationToken), + Operations.ListAsync(Id.ResourceGroupName, Id.Name, cancellationToken), convertor()); } @@ -117,14 +122,14 @@ public AsyncPageable ListAsync(CancellationToken cancellationToken = def /// public override ArmResponse Get(string subnetName, CancellationToken cancellationToken = default) { - return new PhArmResponse(Operations.Get(Id.ResourceGroup, Id.Name, subnetName, cancellationToken: cancellationToken), + return new PhArmResponse(Operations.Get(Id.ResourceGroupName, Id.Name, subnetName, cancellationToken: cancellationToken), n => new Subnet(Parent, new SubnetData(n))); } /// public override async Task> GetAsync(string subnetName, CancellationToken cancellationToken = default) { - return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroup, Id.Name, subnetName, null, cancellationToken), + return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroupName, Id.Name, subnetName, null, cancellationToken), n => new Subnet(Parent, new SubnetData(n))); } } diff --git a/sdk/resourcemanager/Proto.Client/network/SubnetOperations.cs b/sdk/resourcemanager/Proto.Client/network/SubnetOperations.cs index 09e3093ba781..5ab4f9bd5372 100644 --- a/sdk/resourcemanager/Proto.Client/network/SubnetOperations.cs +++ b/sdk/resourcemanager/Proto.Client/network/SubnetOperations.cs @@ -9,7 +9,7 @@ namespace Proto.Network /// /// A class representing the operations that can be performed over a specific subnet. /// - public class SubnetOperations : ResourceOperationsBase, IDeletableResource + public class SubnetOperations : ResourceOperationsBase, IDeletableResource { /// /// Initializes a new instance of the class. @@ -17,7 +17,7 @@ public class SubnetOperations : ResourceOperationsBase, IDeletableResour /// The client parameters to use in these operations. /// The name of the subnet. internal SubnetOperations(VirtualNetworkOperations virtualNetwork, string subnetName) - : base(virtualNetwork, $"{virtualNetwork.Id}/subnets/{subnetName}") + : base(virtualNetwork, virtualNetwork.Id.AppendChildResource( "subnets", subnetName)) { } @@ -42,7 +42,7 @@ protected SubnetOperations(ResourceOperationsBase options, ResourceIdentifier id protected override ResourceType ValidResourceType => ResourceType; private SubnetsOperations Operations => new NetworkManagementClient( - Id.Subscription, + Id.SubscriptionId, BaseUri, Credential, ClientOptions.Convert()).Subnets; @@ -50,14 +50,14 @@ protected SubnetOperations(ResourceOperationsBase options, ResourceIdentifier id /// public ArmResponse Delete(CancellationToken cancellationToken = default) { - return new ArmResponse(Operations.StartDelete(Id.ResourceGroup, Id.Parent.Name, Id.Name, cancellationToken) + return new ArmResponse(Operations.StartDelete(Id.ResourceGroupName, Id.Parent.Name, Id.Name, cancellationToken) .WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } /// public async Task> DeleteAsync(CancellationToken cancellationToken = default) { - return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Parent.Name, Id.Name, cancellationToken)) + return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Parent.Name, Id.Name, cancellationToken)) .WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } @@ -65,26 +65,26 @@ public async Task> DeleteAsync(CancellationToken cancellat /// public ArmOperation StartDelete(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroup, Id.Parent.Name, Id.Name, cancellationToken)); + return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroupName, Id.Parent.Name, Id.Name, cancellationToken)); } /// public async Task> StartDeleteAsync(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Parent.Name, Id.Name, cancellationToken)); + return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Parent.Name, Id.Name, cancellationToken)); } /// public override ArmResponse Get(CancellationToken cancellationToken = default) { - return new PhArmResponse(Operations.Get(Id.ResourceGroup, Id.Parent.Name, Id.Name, cancellationToken: cancellationToken), + return new PhArmResponse(Operations.Get(Id.ResourceGroupName, Id.Parent.Name, Id.Name, cancellationToken: cancellationToken), n => new Subnet(this, new SubnetData(n))); } /// public override async Task> GetAsync(CancellationToken cancellationToken = default) { - return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroup, Id.Parent.Name, Id.Name, null, cancellationToken), + return new PhArmResponse(await Operations.GetAsync(Id.ResourceGroupName, Id.Parent.Name, Id.Name, null, cancellationToken), n => new Subnet(this, new SubnetData(n))); } } diff --git a/sdk/resourcemanager/Proto.Client/network/VirtualNetworkContainer.cs b/sdk/resourcemanager/Proto.Client/network/VirtualNetworkContainer.cs index f4ba5849847f..d7a753904a57 100644 --- a/sdk/resourcemanager/Proto.Client/network/VirtualNetworkContainer.cs +++ b/sdk/resourcemanager/Proto.Client/network/VirtualNetworkContainer.cs @@ -16,7 +16,7 @@ namespace Proto.Network /// /// A class representing collection of virtual network and their operations over a resource group. /// - public class VirtualNetworkContainer : ResourceContainerBase + public class VirtualNetworkContainer : ResourceContainerBase { /// /// Initializes a new instance of the class. @@ -27,11 +27,16 @@ internal VirtualNetworkContainer(ResourceGroupOperations resourceGroup) { } + /// + /// Typed Resource Identifier for the container. + /// + public new ResourceGroupResourceIdentifier Id => base.Id as ResourceGroupResourceIdentifier; + /// protected override ResourceType ValidResourceType => ResourceGroupOperations.ResourceType; private VirtualNetworksOperations Operations => new NetworkManagementClient( - Id.Subscription, + Id.SubscriptionId, BaseUri, Credential, ClientOptions.Convert()).VirtualNetworks; @@ -39,7 +44,7 @@ internal VirtualNetworkContainer(ResourceGroupOperations resourceGroup) /// public override ArmResponse CreateOrUpdate(string name, VirtualNetworkData resourceDetails, CancellationToken cancellationToken = default) { - var operation = Operations.StartCreateOrUpdate(Id.ResourceGroup, name, resourceDetails, cancellationToken); + var operation = Operations.StartCreateOrUpdate(Id.ResourceGroupName, name, resourceDetails, cancellationToken); return new PhArmResponse( operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(), n => new VirtualNetwork(Parent, new VirtualNetworkData(n))); @@ -48,7 +53,7 @@ public override ArmResponse CreateOrUpdate(string name, VirtualN /// public async override Task> CreateOrUpdateAsync(string name, VirtualNetworkData resourceDetails, CancellationToken cancellationToken = default) { - var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails, cancellationToken).ConfigureAwait(false); + var operation = await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails, cancellationToken).ConfigureAwait(false); return new PhArmResponse( await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), n => new VirtualNetwork(Parent, new VirtualNetworkData(n))); @@ -58,7 +63,7 @@ await operation.WaitForCompletionAsync(cancellationToken).ConfigureAwait(false), public override ArmOperation StartCreateOrUpdate(string name, VirtualNetworkData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - Operations.StartCreateOrUpdate(Id.ResourceGroup, name, resourceDetails, cancellationToken), + Operations.StartCreateOrUpdate(Id.ResourceGroupName, name, resourceDetails, cancellationToken), n => new VirtualNetwork(Parent, new VirtualNetworkData(n))); } @@ -66,7 +71,7 @@ public override ArmOperation StartCreateOrUpdate(string name, Vi public async override Task> StartCreateOrUpdateAsync(string name, VirtualNetworkData resourceDetails, CancellationToken cancellationToken = default) { return new PhArmOperation( - await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetails, cancellationToken).ConfigureAwait(false), + await Operations.StartCreateOrUpdateAsync(Id.ResourceGroupName, name, resourceDetails, cancellationToken).ConfigureAwait(false), n => new VirtualNetwork(Parent, new VirtualNetworkData(n))); } @@ -76,9 +81,9 @@ await Operations.StartCreateOrUpdateAsync(Id.ResourceGroup, name, resourceDetail /// The CIDR of the resource. /// The location of the resource. /// A builder with and . - public ArmBuilder Construct(string vnetCidr, LocationData location = null) + public ArmBuilder Construct(string vnetCidr, LocationData location = null) { - var parent = GetParentResource(); + var parent = GetParentResource(); var vnet = new Azure.ResourceManager.Network.Models.VirtualNetwork() { Location = location ?? parent.Data.Location, @@ -86,7 +91,7 @@ public ArmBuilder Construct(string vnetCidr, }; vnet.AddressSpace.AddressPrefixes.Add(vnetCidr); - return new ArmBuilder(this, new VirtualNetworkData(vnet)); + return new ArmBuilder(this, new VirtualNetworkData(vnet)); } /// @@ -178,7 +183,7 @@ public AsyncPageable ListAsync(string nameFilter, int? top = nul public override ArmResponse Get(string virtualNetworkName, CancellationToken cancellationToken = default) { return new PhArmResponse( - Operations.Get(Id.ResourceGroup, virtualNetworkName, cancellationToken: cancellationToken), + Operations.Get(Id.ResourceGroupName, virtualNetworkName, cancellationToken: cancellationToken), Convertor()); } @@ -186,7 +191,7 @@ public override ArmResponse Get(string virtualNetworkName, Cance public override async Task> GetAsync(string virtualNetworkName, CancellationToken cancellationToken = default) { return new PhArmResponse( - await Operations.GetAsync(Id.ResourceGroup, virtualNetworkName, null, cancellationToken), + await Operations.GetAsync(Id.ResourceGroupName, virtualNetworkName, null, cancellationToken), Convertor()); } diff --git a/sdk/resourcemanager/Proto.Client/network/VirtualNetworkOperations.cs b/sdk/resourcemanager/Proto.Client/network/VirtualNetworkOperations.cs index b3fa2a0260ec..79c0df653f68 100644 --- a/sdk/resourcemanager/Proto.Client/network/VirtualNetworkOperations.cs +++ b/sdk/resourcemanager/Proto.Client/network/VirtualNetworkOperations.cs @@ -12,7 +12,7 @@ namespace Proto.Network /// /// A class representing the operations that can be performed over a specific virtual nerwork. /// - public class VirtualNetworkOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource + public class VirtualNetworkOperations : ResourceOperationsBase, ITaggableResource, IDeletableResource { /// /// Initializes a new instance of the class. @@ -29,7 +29,7 @@ internal VirtualNetworkOperations(GenericResourceOperations genericOperations) /// The client parameters to use in these operations. /// The name of the virtual network to use. internal VirtualNetworkOperations(ResourceGroupOperations resourceGroup, string vnetName) - : base(resourceGroup, $"{resourceGroup.Id}/providers/Microsoft.Network/virtualNetworks/{vnetName}") + : base(resourceGroup, resourceGroup.Id.AppendProviderResource(ResourceType.Namespace, ResourceType.Type, vnetName)) { } @@ -54,7 +54,7 @@ protected VirtualNetworkOperations(ResourceOperationsBase options, ResourceIdent protected override ResourceType ValidResourceType => ResourceType; private VirtualNetworksOperations Operations => new NetworkManagementClient( - Id.Subscription, + Id.SubscriptionId, BaseUri, Credential, ClientOptions.Convert()).VirtualNetworks; @@ -62,32 +62,32 @@ protected VirtualNetworkOperations(ResourceOperationsBase options, ResourceIdent /// public ArmResponse Delete(CancellationToken cancellationToken = default) { - return new ArmResponse(Operations.StartDelete(Id.ResourceGroup, Id.Name, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); + return new ArmResponse(Operations.StartDelete(Id.ResourceGroupName, Id.Name, cancellationToken).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } /// public async Task> DeleteAsync(CancellationToken cancellationToken = default) { - return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); + return new ArmResponse((await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)).WaitForCompletionAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); } /// public ArmOperation StartDelete(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(Operations.StartDelete(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// public async Task> StartDeleteAsync(CancellationToken cancellationToken = default) { - return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroup, Id.Name, cancellationToken)); + return new ArmVoidOperation(await Operations.StartDeleteAsync(Id.ResourceGroupName, Id.Name, cancellationToken)); } /// public override ArmResponse Get(CancellationToken cancellationToken = default) { return new PhArmResponse( - Operations.Get(Id.ResourceGroup, Id.Name, cancellationToken: cancellationToken), + Operations.Get(Id.ResourceGroupName, Id.Name, cancellationToken: cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -95,7 +95,7 @@ public override ArmResponse Get(CancellationToken cancellationTo public async override Task> GetAsync(CancellationToken cancellationToken = default) { return new PhArmResponse( - await Operations.GetAsync(Id.ResourceGroup, Id.Name, null, cancellationToken), + await Operations.GetAsync(Id.ResourceGroupName, Id.Name, null, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -107,7 +107,7 @@ public ArmResponse AddTag(string key, string value, Cancellation patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; return new PhArmResponse( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -119,7 +119,7 @@ public async Task> AddTagAsync(string key, string va patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; return new PhArmResponse( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -131,7 +131,7 @@ public ArmOperation StartAddTag(string key, string value, Cancel patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; return new PhArmOperation( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -143,7 +143,7 @@ public async Task> StartAddTagAsync(string key, str patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags[key] = value; return new PhArmOperation( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -172,7 +172,7 @@ public ArmResponse SetTags(IDictionary tags, Can var patchable = new TagsObject(); patchable.Tags.ReplaceWith(tags); return new PhArmResponse( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -182,7 +182,7 @@ public async Task> SetTagsAsync(IDictionary( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -192,7 +192,7 @@ public ArmOperation StartSetTags(IDictionary tag var patchable = new TagsObject(); patchable.Tags.ReplaceWith(tags); return new PhArmOperation( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -202,7 +202,7 @@ public async Task> StartSetTagsAsync(IDictionary( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -214,7 +214,7 @@ public ArmResponse RemoveTag(string key, CancellationToken cance patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); return new PhArmResponse( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -226,7 +226,7 @@ public async Task> RemoveTagAsync(string key, Cancel patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); return new PhArmResponse( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -238,7 +238,7 @@ public ArmOperation StartRemoveTag(string key, CancellationToken patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); return new PhArmOperation( - Operations.UpdateTags(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + Operations.UpdateTags(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } @@ -250,7 +250,7 @@ public async Task> StartRemoveTagAsync(string key, patchable.Tags.ReplaceWith(resource.Data.Tags); patchable.Tags.Remove(key); return new PhArmOperation( - await Operations.UpdateTagsAsync(Id.ResourceGroup, Id.Name, patchable, cancellationToken), + await Operations.UpdateTagsAsync(Id.ResourceGroupName, Id.Name, patchable, cancellationToken), n => new VirtualNetwork(this, new VirtualNetworkData(n))); } diff --git a/sdk/resourcemanager/Proto.Client/src/Program.cs b/sdk/resourcemanager/Proto.Client/src/Program.cs index 8a34634baaf1..3f59b92f10dc 100644 --- a/sdk/resourcemanager/Proto.Client/src/Program.cs +++ b/sdk/resourcemanager/Proto.Client/src/Program.cs @@ -18,8 +18,8 @@ static void Main(string[] args) { foreach (var rgId in Scenario.CleanUp) { - ResourceIdentifier id = new ResourceIdentifier(rgId); - var rg = new AzureResourceManagerClient(new DefaultAzureCredential()).GetSubscriptionOperations(id.Subscription).GetResourceGroupOperations(id.ResourceGroup); + var id = new ResourceGroupResourceIdentifier(rgId); + var rg = new AzureResourceManagerClient(new DefaultAzureCredential()).GetSubscriptionOperations(id.SubscriptionId).GetResourceGroupOperations(id.ResourceGroupName); Console.WriteLine($"--------Deleting {rg.Id.Name}--------"); try { diff --git a/sdk/resourcemanager/Proto.Client/src/Scenarios/All.cs b/sdk/resourcemanager/Proto.Client/src/Scenarios/All.cs index 0e81b3bf995e..16701c88b873 100644 --- a/sdk/resourcemanager/Proto.Client/src/Scenarios/All.cs +++ b/sdk/resourcemanager/Proto.Client/src/Scenarios/All.cs @@ -28,8 +28,8 @@ public override void Execute() { foreach (var rgId in CleanUp) { - ResourceIdentifier id = new ResourceIdentifier(rgId); - var rg = new AzureResourceManagerClient(new DefaultAzureCredential()).GetResourceGroupOperations(rgId); + var id = new ResourceGroupResourceIdentifier(rgId); + var rg = new AzureResourceManagerClient(new DefaultAzureCredential()).GetResourceGroupOperations(id); Console.WriteLine($"--------Deleting {rg.Id.Name}--------"); try { diff --git a/sdk/resourcemanager/Proto.Client/src/Scenarios/CheckResourceGroupOpsAsync.cs b/sdk/resourcemanager/Proto.Client/src/Scenarios/CheckResourceGroupOpsAsync.cs index 410fc85a1bc8..a2b8cdebcb85 100644 --- a/sdk/resourcemanager/Proto.Client/src/Scenarios/CheckResourceGroupOpsAsync.cs +++ b/sdk/resourcemanager/Proto.Client/src/Scenarios/CheckResourceGroupOpsAsync.cs @@ -54,12 +54,12 @@ await ShouldThrowAsync( var data = aset.Get().Value.Data; ShouldThrow( - () => rgOps.CreateResource("", data), + () => rgOps.CreateResource("", data), "CreateResource with empty string didn't throw", "CreateResource"); await ShouldThrowAsync( - async () => await rgOps.CreateResourceAsync(" ", data), + async () => await rgOps.CreateResourceAsync(" ", data), "CreateResourceAsync with whitespaces string didn't throw", "CreateResourceAsync"); @@ -104,12 +104,12 @@ await ShouldThrowAsync( "StartRemoveTagAsync"); ShouldThrow( - () => rgOps.CreateResource("tester", null), + () => rgOps.CreateResource("tester", null), "CreateResource model exception not thrown", "CreateResource"); await ShouldThrowAsync( - async () => await rgOps.CreateResourceAsync("tester", null), + async () => await rgOps.CreateResourceAsync("tester", null), "CreateResourceAsync model exception not thrown", "CreateResourceAsync"); diff --git a/sdk/resourcemanager/Proto.Client/src/Scenarios/DefaultSubscription.cs b/sdk/resourcemanager/Proto.Client/src/Scenarios/DefaultSubscription.cs index b10efaac9997..7085cc73505a 100644 --- a/sdk/resourcemanager/Proto.Client/src/Scenarios/DefaultSubscription.cs +++ b/sdk/resourcemanager/Proto.Client/src/Scenarios/DefaultSubscription.cs @@ -17,14 +17,9 @@ public override void Execute() Console.WriteLine("Found correct subscription"); - client = new AzureResourceManagerClient(new DefaultAzureCredential()); - - sub = client.DefaultSubscription; - - if (sub.Data.SubscriptionGuid != Context.SubscriptionId) - throw new Exception($"Didn't get back expected subscription. Got {sub.Data.SubscriptionGuid} expected {Context.SubscriptionId}"); - - Console.WriteLine("Found correct subscription"); + // Note: check of default subscription without specifying subscription is dependent on the credentials + // used in constructuing the client. Removed this test as its outcome is unpredictable unless you + // always use the same credentials. } } } diff --git a/sdk/resourcemanager/Proto.Client/src/Scenarios/ShutdownVmsByName.cs b/sdk/resourcemanager/Proto.Client/src/Scenarios/ShutdownVmsByName.cs index 746810e2f5e5..162008c69c9a 100644 --- a/sdk/resourcemanager/Proto.Client/src/Scenarios/ShutdownVmsByName.cs +++ b/sdk/resourcemanager/Proto.Client/src/Scenarios/ShutdownVmsByName.cs @@ -17,9 +17,9 @@ public override void Execute() foreach(var armResource in sub.ListVirtualMachinesByName("-e")) { var vmOperations = VirtualMachineOperations.FromGeneric(armResource); - Console.WriteLine($"Stopping {armResource.Id.ResourceGroup} : {armResource.Id.Name}"); + Console.WriteLine($"Stopping {vmOperations.Id.ResourceGroupName} : {armResource.Id.Name}"); vmOperations.PowerOff(); - Console.WriteLine($"Starting {armResource.Id.ResourceGroup} : {armResource.Id.Name}"); + Console.WriteLine($"Starting {vmOperations.Id.ResourceGroupName} : {armResource.Id.Name}"); vmOperations.PowerOn(); } diff --git a/sdk/resourcemanager/Proto.Client/src/Scenarios/ShutdownVmsByNameAcrossResourceGroups.cs b/sdk/resourcemanager/Proto.Client/src/Scenarios/ShutdownVmsByNameAcrossResourceGroups.cs index 4c8c10bd10b7..c8cbf11a9ed4 100644 --- a/sdk/resourcemanager/Proto.Client/src/Scenarios/ShutdownVmsByNameAcrossResourceGroups.cs +++ b/sdk/resourcemanager/Proto.Client/src/Scenarios/ShutdownVmsByNameAcrossResourceGroups.cs @@ -27,9 +27,9 @@ public override void Execute() { if (reg.IsMatch(vm.Id.Name)) { - Console.WriteLine($"Stopping {vm.Id.ResourceGroup} {vm.Id.Name}"); + Console.WriteLine($"Stopping {vm.Id.ResourceGroupName} {vm.Id.Name}"); vm.PowerOff(); - Console.WriteLine($"Starting {vm.Id.ResourceGroup} {vm.Id.Name}"); + Console.WriteLine($"Starting {vm.Id.ResourceGroupName} {vm.Id.Name}"); vm.PowerOn(); } }); diff --git a/sdk/resourcemanager/Proto.Client/src/Scenarios/ShutdownVmsByNameAcrossSubscriptions.cs b/sdk/resourcemanager/Proto.Client/src/Scenarios/ShutdownVmsByNameAcrossSubscriptions.cs index 0a1f64204998..cb8a2eb22a12 100644 --- a/sdk/resourcemanager/Proto.Client/src/Scenarios/ShutdownVmsByNameAcrossSubscriptions.cs +++ b/sdk/resourcemanager/Proto.Client/src/Scenarios/ShutdownVmsByNameAcrossSubscriptions.cs @@ -47,9 +47,9 @@ public async override void Execute() await foreach (var armResource in sub.ListVirtualMachinesByNameAsync("-e")) { var vmOperations = VirtualMachineOperations.FromGeneric(armResource); - Console.WriteLine($"Stopping {vmOperations.Id.Subscription} {vmOperations.Id.ResourceGroup} {vmOperations.Id.Name}"); + Console.WriteLine($"Stopping {vmOperations.Id.SubscriptionId} {vmOperations.Id.ResourceGroupName} {vmOperations.Id.Name}"); vmOperations.PowerOff(); - Console.WriteLine($"Starting {vmOperations.Id.Subscription} {vmOperations.Id.ResourceGroup} {vmOperations.Id.Name}"); + Console.WriteLine($"Starting {vmOperations.Id.SubscriptionId} {vmOperations.Id.ResourceGroupName} {vmOperations.Id.Name}"); vmOperations.PowerOn(); } } diff --git a/sdk/resourcemanager/Proto.Client/src/Scenarios/TenantResource.cs b/sdk/resourcemanager/Proto.Client/src/Scenarios/TenantResource.cs index 36f5a850857d..306b43e72518 100644 --- a/sdk/resourcemanager/Proto.Client/src/Scenarios/TenantResource.cs +++ b/sdk/resourcemanager/Proto.Client/src/Scenarios/TenantResource.cs @@ -12,7 +12,9 @@ public override void Execute() { var client = new AzureResourceManagerClient(new DefaultAzureCredential()); TenantOperations tenant = client.Tenant; - string testAccount = "3984c6f4-2d2a-4b04-93ce-43cf4824b698:e2f1492a-a492-468d-909f-bf7fe6662c01_2019-05-31"; + string testAccount = "9b84fb4c-c79a-4819-bd24-1e58f88885bd"; + // old value: "3984c6f4-2d2a-4b04-93ce-43cf4824b698:e2f1492a-a492-468d-909f-bf7fe6662c01_2019-05-31"; + // Note that the account may or may not be accessible, depending on your credentials BillingAccountOperations billingAccountOperations = tenant.GetBillingAccountsOperations(testAccount); var account = billingAccountOperations.Get(); Debug.Assert(account.Value.Data.Name.Equals(testAccount));