Skip to content

Commit 68f0b72

Browse files
committed
Fix the bug that Get-AzResource will not return what we expect when the server forget to return the api-version of the resource type
1 parent c929be5 commit 68f0b72

File tree

5 files changed

+132
-2
lines changed

5 files changed

+132
-2
lines changed

src/Resources/ResourceManager/Components/ApiVersionHelper.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Components
2626
using System.Linq;
2727
using System.Threading;
2828
using System.Threading.Tasks;
29-
// TODO: Remove IfDef
29+
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Utilities;
30+
// TODO: Remove IfDef
3031
#if NETSTANDARD
3132
using Microsoft.Extensions.Caching.Memory;
3233
#else
@@ -127,13 +128,28 @@ private static string[] GetApiVersionsForResourceType(IAzureContext context, str
127128
cancellationToken: cancellationToken),
128129
cancellationToken: cancellationToken);
129130

130-
return providers
131+
string[] apiVersions = providers
131132
.CoalesceEnumerable()
132133
.Where(provider => providerNamespace.EqualsInsensitively(provider.Namespace))
133134
.SelectMany(provider => provider.ResourceTypes)
134135
.Where(type => resourceType.EqualsInsensitively(type.ResourceType))
135136
.Select(type => type.ApiVersions)
136137
.FirstOrDefault();
138+
if (apiVersions == null)
139+
{
140+
string topLevelResourceType = ResourceTypeUtility.GetTopLevelResourceType(resourceType);
141+
return providers
142+
.CoalesceEnumerable()
143+
.Where(provider => providerNamespace.EqualsInsensitively(provider.Namespace))
144+
.SelectMany(provider => provider.ResourceTypes)
145+
.Where(type => topLevelResourceType.EqualsInsensitively(type.ResourceType))
146+
.Select(type => type.ApiVersions)
147+
.FirstOrDefault();
148+
}
149+
else
150+
{
151+
return apiVersions;
152+
}
137153
}
138154

139155
/// <summary>

src/Resources/ResourceManager/SdkClient/ResourceManagerSdkClient.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
using Microsoft.Azure.Commands.ResourceManager.Common.Paging;
4141
using System.Management.Automation;
4242
using Microsoft.Rest;
43+
using System.Runtime.InteropServices.ComTypes;
4344

4445
namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkClient
4546
{
@@ -1168,6 +1169,13 @@ public virtual PSResource GetById(string resourceId, string apiVersion)
11681169
var resourceType = provider.ResourceTypes
11691170
.Where(t => string.Equals(string.Format("{0}/{1}", provider.NamespaceProperty, t.ResourceType), resourceIdentifier.ResourceType, StringComparison.OrdinalIgnoreCase))
11701171
.FirstOrDefault();
1172+
if (resourceType == null)
1173+
{
1174+
string topLevelResourceType = ResourceTypeUtility.GetTopLevelResourceTypeWithProvider(resourceIdentifier.ResourceType);
1175+
resourceType = provider.ResourceTypes
1176+
.Where(t => string.Equals(t.ResourceType, topLevelResourceType, StringComparison.OrdinalIgnoreCase))
1177+
.FirstOrDefault();
1178+
}
11711179
if (resourceType != null)
11721180
{
11731181
apiVersion = resourceType.ApiVersions.Contains(apiVersion) ? apiVersion : resourceType.ApiVersions.FirstOrDefault();
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Utilities
6+
{
7+
public static class ResourceTypeUtility
8+
{
9+
public static string GetTopLevelResourceType(string resourceType)
10+
{
11+
if (string.IsNullOrEmpty(resourceType))
12+
{
13+
return null;
14+
}
15+
string[] resourceTypeFieldList = resourceType.Split('/');
16+
// resourceType is like {topLevelResource}/[{subLevelResource}]
17+
return resourceTypeFieldList[0];
18+
}
19+
20+
public static string GetTopLevelResourceTypeWithProvider(string resourceType)
21+
{
22+
if (string.IsNullOrEmpty(resourceType))
23+
{
24+
return null;
25+
}
26+
string[] resourceTypeFieldList = resourceType.Split('/');
27+
// resourceType is like {provider}/{topLevelResource}/[{subLevelResource}]
28+
if (resourceTypeFieldList.Length >= 1)
29+
{
30+
return resourceTypeFieldList[1];
31+
}
32+
else
33+
{
34+
return resourceType;
35+
}
36+
}
37+
}
38+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Xunit;
5+
using Xunit.Abstractions;
6+
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Utilities;
7+
using Microsoft.WindowsAzure.Commands.ScenarioTest;
8+
9+
namespace Microsoft.Azure.Commands.Resources.Test.UnitTests.Utilities
10+
{
11+
public class TestResourceTypeUtility
12+
{
13+
[Fact]
14+
[Trait(Category.AcceptanceType, Category.CheckIn)]
15+
public void TestInputIsNull()
16+
{
17+
string resourceType = ResourceTypeUtility.GetTopLevelResourceType(null);
18+
19+
Assert.Null(resourceType);
20+
}
21+
22+
[Fact]
23+
[Trait(Category.AcceptanceType, Category.CheckIn)]
24+
public void TestInputTopLevelResourceTypeSingle()
25+
{
26+
string resourceType = ResourceTypeUtility.GetTopLevelResourceType("virtualMachines");
27+
28+
Assert.Equal("virtualMachines", resourceType);
29+
}
30+
31+
[Fact]
32+
[Trait(Category.AcceptanceType, Category.CheckIn)]
33+
public void TestInputTopLevelResourceTypeAndSubResourceType()
34+
{
35+
string resourceType = ResourceTypeUtility.GetTopLevelResourceType("virtualMachines/networking");
36+
37+
Assert.Equal("virtualMachines", resourceType);
38+
}
39+
40+
[Fact]
41+
[Trait(Category.AcceptanceType, Category.CheckIn)]
42+
public void TestInputProviderNull()
43+
{
44+
string resourceType = ResourceTypeUtility.GetTopLevelResourceTypeWithProvider(null);
45+
46+
Assert.Null(resourceType);
47+
}
48+
49+
[Fact]
50+
[Trait(Category.AcceptanceType, Category.CheckIn)]
51+
public void TestInputProviderAndTopLevelResourceType()
52+
{
53+
string resourceType = ResourceTypeUtility.GetTopLevelResourceTypeWithProvider("Microsoft.Compute/virtualMachines");
54+
55+
Assert.Equal("virtualMachines", resourceType);
56+
}
57+
58+
[Fact]
59+
[Trait(Category.AcceptanceType, Category.CheckIn)]
60+
public void TestInputProviderAndTopLevelResourceTypeAndSubLevelResourceType()
61+
{
62+
string resourceType = ResourceTypeUtility.GetTopLevelResourceTypeWithProvider("Microsoft.Compute/virtualMachines/networking");
63+
64+
Assert.Equal("virtualMachines", resourceType);
65+
}
66+
}
67+
}

src/Resources/Resources/ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
* Update references in .psd1 to use relative path
2222
* Fix an issue where template deployment fails to read a template parameter if its name conflicts with some built-in parameter name.
2323
* Updated policy cmdlets to use new api version 2019-09-01 that introduces grouping support within policy set definitions.
24+
* Fix the bug that the output of some sub-resource is empty when using `Get-AzResource`.
2425

2526
## Version 1.8.0
2627
- Updated policy cmdlets to use new api version 2019-06-01 that has new EnforcementMode property in policy assignment.

0 commit comments

Comments
 (0)