Skip to content

New-AzureRmVm/VMSS: verbose parameter output. #5933

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/ResourceManager/Compute/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- Additional information about change #1
-->
## Current Release
* `New-AzureRmVm` and `New-AzureRmVmss` support verbose output of parameters
* `New-AzureRmVm` and `New-AzureRmVmss` (simple parameter set) support assigning user defined and(or) system defined identities to the VM(s).
* VMSS Redeploy and PerformMaintenance feature
- Add new switch parameter -Redeploy and -PerformMaintenance to `Set-AzureRmVmss` and `Set-AzureRmVmssVM`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Microsoft.Azure.Commands.Common.Strategies;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Threading.Tasks;

Expand All @@ -30,10 +31,11 @@ public static void WriteVerbose(this IAsyncCmdlet cmdlet, string message, params
/// </summary>
/// <param name="cmdlet"></param>
/// <param name="createAndStartTask"></param>
public static void StartAndWait(
this Cmdlet cmdlet, Func<IAsyncCmdlet, Task> createAndStartTask)
public static void StartAndWait<T>(
this T cmdlet, Func<IAsyncCmdlet, Task> createAndStartTask)
where T : PSCmdlet
{
var asyncCmdlet = new AsyncCmdlet(cmdlet);
var asyncCmdlet = new AsyncCmdlet<T>(cmdlet);
string previousX = null;
string previousOperation = null;
asyncCmdlet.Scheduler.Wait(
Expand Down Expand Up @@ -79,20 +81,37 @@ public static void StartAndWait(
});
}

sealed class AsyncCmdlet : IAsyncCmdlet
sealed class AsyncCmdlet<T> : IAsyncCmdlet
where T : PSCmdlet
{
public SyncTaskScheduler Scheduler { get; } = new SyncTaskScheduler();

readonly Cmdlet _Cmdlet;
readonly T _Cmdlet;

public List<ITaskProgress> TaskProgressList { get; }
= new List<ITaskProgress>();

public AsyncCmdlet(Cmdlet cmdlet)
public AsyncCmdlet(T cmdlet)
{
_Cmdlet = cmdlet;
}

public IEnumerable<KeyValuePair<string, object>> Parameters
{
get
{
var psName = _Cmdlet.ParameterSetName;
return typeof(T)
.GetProperties()
.Where(p => p
.GetCustomAttributes(false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should check for null here, what if there is a random class property that does not have any custom attributes... will the code here throw a null ptr exception?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.OfType<ParameterAttribute>()
.Any(a => a.ParameterSetName == psName
|| a.ParameterSetName == null))
.Select(p => new KeyValuePair<string, object>(p.Name, p.GetValue(_Cmdlet)));
}
}

public void WriteVerbose(string message)
=> Scheduler.BeginInvoke(() => _Cmdlet.WriteVerbose(message));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@
// ----------------------------------------------------------------------------------

using Microsoft.Azure.Commands.Common.Strategies;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Microsoft.Azure.Commands.Compute.Strategies
{
interface IAsyncCmdlet
{
IEnumerable<KeyValuePair<string, object>> Parameters { get; }

void WriteVerbose(string message);

Task<bool> ShouldProcessAsync(string target, string action);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Microsoft.Azure.Commands.Common.Strategies;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -28,6 +31,11 @@ public static async Task<TModel> RunAsync<TModel>(
var engine = new SdkEngine(client.SubscriptionId);
var target = config.GetTargetState(current, engine, parameters.Location);

foreach (var p in asyncCmdlet.Parameters)
{
asyncCmdlet.WriteVerbose(p.Key + " = " + ToPowerShellString(p.Value));
}

// apply target state
var newState = await config.UpdateStateAsync(
client,
Expand All @@ -38,5 +46,24 @@ public static async Task<TModel> RunAsync<TModel>(

return newState.Get(config) ?? current.Get(config);
}

static string ToPowerShellString(object value)
{
if (value == null)
{
return "$null";
}
var s = value as string;
if (s != null)
{
return "\"" + s + "\"";
}
var e = value as IEnumerable;
if (e != null)
{
return string.Join(",", e.Cast<object>().Select(ToPowerShellString));
}
return value.ToString();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so for this, if the type of the parameter (specifically for custom defined classes) does not implement a ToString() this would just print out the object type instead of a string representation of the data in the object? Do we want to do this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, if we don't know the type we use object.ToString() function. This's also default PowerShell behavior.

}
}
}