diff --git a/src/ResourceManager/Resources/Commands.Resources.Test/Providers/GetAzureProviderCmdletTests.cs b/src/ResourceManager/Resources/Commands.Resources.Test/Providers/GetAzureProviderCmdletTests.cs index 8ffbce848eb0..0d71642c3283 100644 --- a/src/ResourceManager/Resources/Commands.Resources.Test/Providers/GetAzureProviderCmdletTests.cs +++ b/src/ResourceManager/Resources/Commands.Resources.Test/Providers/GetAzureProviderCmdletTests.cs @@ -91,7 +91,7 @@ public void GetsResourceProviderTests() { new ProviderResourceType { - Locations = new[] {"West US", "East US"}, + Locations = new[] {"West US", "East US", "South US"}, Name = "TestResource2" } } @@ -197,6 +197,52 @@ public void GetsResourceProviderTests() this.cmdlet.ExecuteCmdlet(); this.VerifyGetCallPatternAndReset(); + + // 4. List only registered providers with location + this.cmdlet.Location = "South US"; + this.cmdlet.ListAvailable = false; + this.cmdlet.ProviderNamespace = null; + + this.commandRuntimeMock + .Setup(m => m.WriteObject(It.IsAny())) + .Callback((object obj) => + { + Assert.IsType(obj); + + var providers = (PSResourceProvider[])obj; + Assert.Equal(0, providers.Length); + }); + + this.cmdlet.ParameterSetOverride = GetAzureProviderCmdlet.ListAvailableParameterSet; + + this.cmdlet.ExecuteCmdlet(); + + this.VerifyListCallPatternAndReset(); + + // 5. List all providers + this.cmdlet.ListAvailable = true; + this.cmdlet.Location = "South US"; + this.cmdlet.ProviderNamespace = null; + + this.commandRuntimeMock + .Setup(m => m.WriteObject(It.IsAny())) + .Callback((object obj) => + { + var providers = (PSResourceProvider[])obj; + Assert.Equal(0, providers.Length); + + var provider = providers.Single(); + Assert.Equal(UnregisteredProviderNamespace, provider.ProviderNamespace); + + Assert.Equal(1, provider.ResourceTypes.Length); + + var resourceType = provider.ResourceTypes.Single(); + Assert.Equal(ResourceTypeName, resourceType.ResourceTypeName); + }); + + this.cmdlet.ExecuteCmdlet(); + + this.VerifyListCallPatternAndReset(); } /// diff --git a/src/ResourceManager/Resources/Commands.Resources/Models.ResourceGroups/PSResourceProvider.cs b/src/ResourceManager/Resources/Commands.Resources/Models.ResourceGroups/PSResourceProvider.cs index 5e539bfb53c9..ef8cbe1cd320 100644 --- a/src/ResourceManager/Resources/Commands.Resources/Models.ResourceGroups/PSResourceProvider.cs +++ b/src/ResourceManager/Resources/Commands.Resources/Models.ResourceGroups/PSResourceProvider.cs @@ -14,6 +14,9 @@ namespace Microsoft.Azure.Commands.Resources.Models { + using System; + using System.Linq; + /// /// Definition of a resource provider and its registration state /// @@ -33,5 +36,19 @@ public class PSResourceProvider /// Gets or sets the resource types belonging to this provider. /// public PSResourceProviderResourceType[] ResourceTypes { get; set; } + + /// + /// Gets the locations for the provider. + /// + public string[] Locations + { + get + { + return this.ResourceTypes + .SelectMany(type => type.Locations) + .Distinct(StringComparer.InvariantCultureIgnoreCase) + .ToArray(); + } + } } } diff --git a/src/ResourceManager/Resources/Commands.Resources/Models.ResourceGroups/ResourceClient.cs b/src/ResourceManager/Resources/Commands.Resources/Models.ResourceGroups/ResourceClient.cs index 3f22f04d4a07..480df4751055 100644 --- a/src/ResourceManager/Resources/Commands.Resources/Models.ResourceGroups/ResourceClient.cs +++ b/src/ResourceManager/Resources/Commands.Resources/Models.ResourceGroups/ResourceClient.cs @@ -394,16 +394,26 @@ internal List GetResourcePermissions(ResourceIdentifier identity) return null; } - public virtual PSResourceProvider[] ListPSResourceProviders(string providerName = null) + public virtual PSResourceProvider[] ListPSResourceProviders(string providerName = null, bool listAvailable = false, string location = null) { - return this.ListResourceProviders(providerName: providerName, listAvailable: false) - .Select(provider => provider.ToPSResourceProvider()) - .ToArray(); - } + var providers = this.ListResourceProviders(providerName: providerName, listAvailable: listAvailable); - public virtual PSResourceProvider[] ListPSResourceProviders(bool listAvailable) - { - return this.ListResourceProviders(providerName: null, listAvailable: listAvailable) + if (string.IsNullOrEmpty(location)) + { + return providers + .Select(provider => provider.ToPSResourceProvider()) + .ToArray(); + } + + foreach (var provider in providers) + { + provider.ResourceTypes = provider.ResourceTypes + .Where(type => !type.Locations.Any() || this.ContainsNormalizedLocation(type.Locations.ToArray(), location)) + .ToList(); + } + + return providers + .Where(provider => provider.ResourceTypes.Any()) .Select(provider => provider.ToPSResourceProvider()) .ToArray(); } @@ -439,6 +449,16 @@ public virtual List ListResourceProviders(string providerName = null, } } + private bool ContainsNormalizedLocation(string[] locations, string location) + { + return locations.Any(existingLocation => this.NormalizeLetterOrDigitToUpperInvariant(existingLocation).Equals(this.NormalizeLetterOrDigitToUpperInvariant(location))); + } + + private string NormalizeLetterOrDigitToUpperInvariant(string value) + { + return value != null ? new string(value.Where(c => char.IsLetterOrDigit(c)).ToArray()).ToUpperInvariant() : null; + } + private bool IsProviderRegistered(Provider provider) { return string.Equals( diff --git a/src/ResourceManager/Resources/Commands.Resources/Providers/GetAzureProviderCmdlet.cs b/src/ResourceManager/Resources/Commands.Resources/Providers/GetAzureProviderCmdlet.cs index 3dd256c5c3db..741a6fc7c53e 100644 --- a/src/ResourceManager/Resources/Commands.Resources/Providers/GetAzureProviderCmdlet.cs +++ b/src/ResourceManager/Resources/Commands.Resources/Providers/GetAzureProviderCmdlet.cs @@ -15,6 +15,7 @@ namespace Microsoft.Azure.Commands.Providers { using System; + using System.Linq; using System.Management.Automation; using Microsoft.Azure.Commands.Resources.Models; @@ -41,6 +42,13 @@ public class GetAzureProviderCmdlet : ResourcesBaseCmdlet [ValidateNotNullOrEmpty] public string ProviderNamespace { get; set; } + /// + /// Gets or sets the provider namespace + /// + [Parameter(Mandatory = false, ValueFromPipelineByPropertyName = false, HelpMessage = "The location to look for provider namespace.")] + [ValidateNotNullOrEmpty] + public string Location { get; set; } + /// /// Gets or sets a value indicating if unregistered providers should be included in the listing /// @@ -52,20 +60,34 @@ public class GetAzureProviderCmdlet : ResourcesBaseCmdlet /// protected override void ProcessRecord() { - var parameterSetName = this.DetermineParameterSetName(); + var providers = this.ResourcesClient.ListPSResourceProviders(providerName: this.ProviderNamespace, listAvailable: this.ListAvailable, location: this.Location); - switch (parameterSetName) + if (!string.IsNullOrEmpty(this.ProviderNamespace)) { - case GetAzureProviderCmdlet.IndividualProviderParameterSet: - this.WriteObject(this.ResourcesClient.ListPSResourceProviders(providerName: this.ProviderNamespace), enumerateCollection: true); - break; - - case GetAzureProviderCmdlet.ListAvailableParameterSet: - this.WriteObject(this.ResourcesClient.ListPSResourceProviders(listAvailable: this.ListAvailable), enumerateCollection: true); - break; + var expandedProviders = providers + .SelectMany(provider => + provider.ResourceTypes + .Select(type => + new PSResourceProvider + { + ProviderNamespace = provider.ProviderNamespace, + RegistrationState = provider.RegistrationState, + ResourceTypes = new[] + { + new PSResourceProviderResourceType + { + ResourceTypeName = type.ResourceTypeName, + Locations = type.Locations, + ApiVersions = type.ApiVersions, + } + } + })); - default: - throw new ApplicationException(string.Format("Unknown parameter set encountered: '{0}'", this.ParameterSetName)); + this.WriteObject(expandedProviders, enumerateCollection: true); + } + else + { + this.WriteObject(providers, enumerateCollection: true); } } }