Skip to content

Commit 121c37c

Browse files
committed
Fix Set and Move AzureResource commands. DefaultParamSet is now ResourceId.
1 parent e3c5862 commit 121c37c

14 files changed

+294
-95
lines changed

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Commands.ResourceManager.Cmdlets.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
<Compile Include="Extensions\IEnumerableExtensions.cs" />
119119
<Compile Include="Extensions\JsonExtensions.cs" />
120120
<Compile Include="Extensions\ObjectExtensions.cs" />
121+
<Compile Include="Extensions\PsObjectExtensions.cs" />
121122
<Compile Include="Extensions\StringExtensions.cs" />
122123
<Compile Include="Handlers\AuthenticationHandler.cs" />
123124
<Compile Include="Handlers\RetryHandler.cs" />

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Components/Constants.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public static class Constants
5252
/// <summary>
5353
/// The move action.
5454
/// </summary>
55-
public static readonly string Move = "move";
55+
public static readonly string MoveResources = "moveResources";
5656

5757
/// <summary>
5858
/// The locks resource type.
@@ -63,5 +63,10 @@ public static class Constants
6363
/// The deployment operations resource type.
6464
/// </summary>
6565
public static readonly string MicrosoftResourcesDeploymentOperationsType = Constants.MicrosoftResourceNamesapce + "/deployments/operations";
66+
67+
/// <summary>
68+
/// The type name of the generic resource.
69+
/// </summary>
70+
public static readonly string MicrosoftAzureResource = "Microsoft.Azure.Resource";
6671
}
6772
}

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Components/LongRunningOperationHelper.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Components
2020
using System.Threading;
2121
using System.Threading.Tasks;
2222
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Collections;
23-
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Components;
2423
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Entities.Resources;
2524
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Extensions;
2625
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.RestClients;
@@ -167,6 +166,11 @@ private TrackingOperationResult HandleCreateOrUpdateResponse(OperationResult ope
167166
: operationResult.Value
168167
.ToObject<Resource<InsensitiveDictionary<JToken>>>(JsonExtensions.JsonObjectTypeSerializer);
169168

169+
if(resource == null && operationResult.HttpStatusCode == HttpStatusCode.Created)
170+
{
171+
return this.SuccessfulResult(operationResult);
172+
}
173+
170174
if (resource == null)
171175
{
172176
this.FailedResult(

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Components/ResourceIdUtility.cs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public static string GetProviderNamespace(string resourceId)
165165
}
166166

167167
/// <summary>
168-
/// Gets the provider namespace from the resource id.
168+
/// Gets the subscription id from the resource id.
169169
/// </summary>
170170
/// <param name="resourceId">The resource id.</param>
171171
public static string GetSubscriptionId(string resourceId)
@@ -174,14 +174,45 @@ public static string GetSubscriptionId(string resourceId)
174174
}
175175

176176
/// <summary>
177-
/// Gets the provider namespace from the resource id.
177+
/// Gets the name of the resource group from the resource id.
178178
/// </summary>
179179
/// <param name="resourceId">The resource id.</param>
180-
public static string GetResourceGroup(string resourceId)
180+
public static string GetResourceGroupName(string resourceId)
181181
{
182182
return ResourceIdUtility.GetNextSegmentAfter(resourceId: resourceId, segmentName: Constants.ResourceGroups);
183183
}
184184

185+
/// <summary>
186+
/// Gets the id of the resource group from the resource id.
187+
/// </summary>
188+
/// <param name="resourceId">The resource id.</param>
189+
public static string GetResourceGroupId(string resourceId)
190+
{
191+
var subscriptionId = ResourceIdUtility.GetSubscriptionId(resourceId);
192+
if (string.IsNullOrWhiteSpace(subscriptionId))
193+
{
194+
return null;
195+
}
196+
197+
Guid subscriptionGuid;
198+
if (!Guid.TryParse(subscriptionId, out subscriptionGuid))
199+
{
200+
return null;
201+
}
202+
203+
var resourceGroupName = ResourceIdUtility.GetResourceGroupName(resourceId);
204+
if (string.IsNullOrWhiteSpace(resourceGroupName))
205+
{
206+
return null;
207+
}
208+
209+
return ResourceIdUtility.GetResourceId(
210+
subscriptionId: subscriptionGuid,
211+
resourceGroupName: resourceGroupName,
212+
resourceType: null,
213+
resourceName: null);
214+
}
215+
185216
/// <summary>
186217
/// Gets a resource type
187218
/// </summary>

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Components/TagsHelper.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,11 @@ internal static InsensitiveDictionary<string> GetTagsDictionary(IEnumerable<Hash
5151
/// Gets a tags hash table from a tags dictionary.
5252
/// </summary>
5353
/// <param name="tags">The tags dictionary.</param>
54-
internal static Hashtable[] GetTagsHashtables(InsensitiveDictionary<string> tags)
54+
internal static List<Hashtable> GetTagsHashtables(InsensitiveDictionary<string> tags)
5555
{
5656
return tags == null
5757
? null
58-
: tags.SelectArray(kvp => new Hashtable
59-
{
60-
{"Name", kvp.Key},
61-
{"Value", kvp.Value},
62-
});
58+
: tags.Select(kvp => new Hashtable { { "Name", kvp.Key }, { "Value", kvp.Value } }).ToList();
6359
}
6460
}
6561
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Extensions
16+
{
17+
using System;
18+
using System.Collections;
19+
using System.Linq;
20+
using System.Management.Automation;
21+
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Components;
22+
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Collections;
23+
using Newtonsoft.Json.Linq;
24+
25+
/// <summary>
26+
/// A helper class that handles common tasks that deal with the <see cref="ResourcePropertyObject"/> class.
27+
/// </summary>
28+
public static class PsObjectExtensions
29+
{
30+
/// <summary>
31+
/// The properties to remove.
32+
/// </summary>
33+
private static readonly InsensitiveDictionary<bool> PropertiesToRemove = new InsensitiveDictionary<bool>
34+
{
35+
{ "ResourceId", false },
36+
{ "ResourceName", false },
37+
{ "ResourceType", false},
38+
{ "ExtensionResourceName", false },
39+
{ "ExtensionResourceType", false },
40+
{ "ResourceGroupName", false },
41+
{ "SubscriptionId", false },
42+
{ "Tags", false },
43+
{ "PropertiesText", false },
44+
};
45+
46+
/// <summary>
47+
/// Converts a <see cref="ResourcePropertyObject"/> to <see cref="JToken"/>
48+
/// </summary>
49+
/// <param name="propertyObject">The <see cref="ResourcePropertyObject"/></param>
50+
internal static JToken ToResourcePropertiesBody(this PSObject propertyObject)
51+
{
52+
return PsObjectExtensions.ToJToken(propertyObject);
53+
}
54+
55+
/// <summary>
56+
/// Helper method for converting <see cref="Object"/> to <see cref="JToken"/>
57+
/// </summary>
58+
/// <param name="value">The object.</param>
59+
private static JToken ToJToken(object value)
60+
{
61+
if (value == null)
62+
{
63+
return null;
64+
}
65+
66+
var valueAsPsObject = value as PSObject;
67+
if (valueAsPsObject != null)
68+
{
69+
JObject obj = new JObject();
70+
if (valueAsPsObject.TypeNames.Any(typeName => typeName.EqualsInsensitively("System.Collections.Hashtable")) && valueAsPsObject.BaseObject is Hashtable)
71+
{
72+
foreach (var dictionaryEntry in ((Hashtable)valueAsPsObject.BaseObject).OfType<DictionaryEntry>())
73+
{
74+
obj.Add(dictionaryEntry.Key.ToString(), PsObjectExtensions.ToJToken(dictionaryEntry.Value));
75+
}
76+
}
77+
else
78+
{
79+
var properties = (valueAsPsObject.TypeNames.Any(typeName => typeName.EqualsInsensitively(Constants.MicrosoftAzureResource)))
80+
? valueAsPsObject.Properties.Where(property => !PsObjectExtensions.PropertiesToRemove.ContainsKey(property.Name))
81+
: valueAsPsObject.Properties.AsEnumerable();
82+
83+
foreach (var member in properties)
84+
{
85+
obj.Add(member.Name, PsObjectExtensions.ToJToken(member.Value));
86+
}
87+
}
88+
89+
return obj;
90+
}
91+
92+
var valueAsArray = value as Array;
93+
if (valueAsArray != null)
94+
{
95+
var retVal = new JToken[valueAsArray.Length];
96+
for (int i = 0; i < valueAsArray.Length; ++i)
97+
{
98+
retVal[i] = PsObjectExtensions.ToJToken(valueAsArray.GetValue(i));
99+
}
100+
101+
return JArray.FromObject(retVal);
102+
}
103+
104+
return new JValue(value.ToString());
105+
}
106+
}
107+
}

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Extensions/ResourceExtensions.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,23 @@ internal static PSObject ToPsObject(this Resource<JToken> resource)
4545
{ "ExtensionResourceName", ResourceIdUtility.GetExtensionResourceName(resource.Id) },
4646
{ "ExtensionResourceType", extensionResourceType },
4747
{ "Kind", resource.Kind },
48-
{ "ResourceGroupName", ResourceIdUtility.GetResourceGroup(resource.Id) },
48+
{ "ResourceGroupName", ResourceIdUtility.GetResourceGroupName(resource.Id) },
4949
{ "Location", resource.Location },
5050
{ "SubscriptionId", ResourceIdUtility.GetSubscriptionId(resource.Id) },
5151
{ "Tags", TagsHelper.GetTagsHashtables(resource.Tags) },
5252
{ "Plan", resource.Plan.ToJToken().ToPsObject() },
5353
{ "Properties", resource.Properties.ToPsObject() },
54-
{ "PropertiesText", resource.Properties == null ? null : resource.Properties.ToString() },
5554
{ "CreatedTime", resource.CreatedTime },
5655
{ "ChangedTime", resource.ChangedTime },
5756
{ "ETag", resource.ETag },
5857
};
5958

60-
return PowerShellUtilities.ConstructPSObject(
59+
var psObject = PowerShellUtilities.ConstructPSObject(
6160
(resourceType + extensionResourceType).Replace('/', '.'),
6261
objectDefinition.Where(kvp => kvp.Value != null).SelectManyArray(kvp => new[] { kvp.Key, kvp.Value }));
62+
63+
psObject.TypeNames.Add(Constants.MicrosoftAzureResource);
64+
return psObject;
6365
}
6466

6567
/// <summary>
@@ -70,5 +72,15 @@ internal static Resource<JToken> ToResource(this JToken jtoken)
7072
{
7173
return jtoken.ToObject<Resource<JToken>>(JsonExtensions.JsonMediaTypeSerializer);
7274
}
75+
76+
/// <summary>00
77+
/// Converts a <see cref="JToken"/> to a <see cref="Resource{JToken}"/>.
78+
/// </summary>
79+
/// <typeparam name="TType">The type of the properties.</typeparam>
80+
/// <param name="jtoken">The <see cref="JToken"/>.</param>
81+
internal static Resource<TType> ToResource<TType>(this JToken jtoken)
82+
{
83+
return jtoken.ToObject<Resource<TType>>(JsonExtensions.JsonMediaTypeSerializer);
84+
}
7385
}
7486
}

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Implementation/GetAzureResourceCmdlet.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ private async Task<JObject> GetResource()
349349
private async Task<ResponseWithContinuation<JObject[]>> ListResourcesTypeCollection()
350350
{
351351
var resourceCollectionId = ResourceIdUtility.GetResourceId(
352-
subscriptionId: this.SubscriptionId.CoalesceEnumerable().FirstOrDefault(),
352+
subscriptionId: this.SubscriptionId.CoalesceEnumerable().Cast<Guid?>().FirstOrDefault(),
353353
resourceGroupName: this.ResourceGroupName,
354354
resourceType: this.ResourceType,
355355
resourceName: this.ResourceName,
@@ -619,7 +619,7 @@ private string GetResourceId()
619619
return !string.IsNullOrWhiteSpace(this.ResourceId)
620620
? this.ResourceId
621621
: ResourceIdUtility.GetResourceId(
622-
subscriptionId: this.SubscriptionId.CoalesceEnumerable().FirstOrDefault(),
622+
subscriptionId: this.SubscriptionId.CoalesceEnumerable().Cast<Guid?>().FirstOrDefault(),
623623
resourceGroupName: this.ResourceGroupName,
624624
resourceType: this.ResourceType,
625625
resourceName: this.ResourceName,
@@ -665,7 +665,7 @@ private bool IsResourceGet()
665665
/// </summary>
666666
private bool IsResourceTypeCollectionGet()
667667
{
668-
return this.IsCollection &&
668+
return (this.IsCollection || this.TenantLevel) &&
669669
(this.IsResourceGroupLevelResourceTypeCollectionGet() ||
670670
this.IsSubscriptionLevelResourceTypeCollectionGet() ||
671671
this.IsTenantLevelResourceTypeCollectionGet());

src/ResourceManager/ResourceManager/Commands.ResourceManager/Cmdlets/Implementation/InvokeAzureResourceActionCmdlet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation
2323
/// <summary>
2424
/// A cmdlet that creates a new azure resource.
2525
/// </summary>
26-
[Cmdlet(VerbsLifecycle.Invoke, "AzureResourceAction", SupportsShouldProcess = true, DefaultParameterSetName = ResourceManipulationCmdletBase.SubscriptionLevelResoruceParameterSet), OutputType(typeof(PSObject))]
26+
[Cmdlet(VerbsLifecycle.Invoke, "AzureResourceAction", SupportsShouldProcess = true, DefaultParameterSetName = ResourceManipulationCmdletBase.ResourceIdParameterSet), OutputType(typeof(PSObject))]
2727
public sealed class InvokAzureResourceActionCmdlet : ResourceManipulationCmdletBase
2828
{
2929
/// <summary>

0 commit comments

Comments
 (0)