Skip to content

Resources improvements #6008

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 19 commits into from
Apr 30, 2018
Merged

Conversation

cormacpayne
Copy link
Member

@cormacpayne cormacpayne commented Apr 20, 2018

Description

Fix for issue #5903

  • Update AD cmdlets so they conform with PowerShell standards
  • Add new parameter set to New-AzureRmADServicePrincipal for simple creation of a service principal
  • Remove Find-AzureRmResource and update Get-AzureRmResource to work in basic scenarios
  • Remove Find-AzureRmResourceGroup and move missing functionality into Get-AzureRmResourceGroup

Checklist

Copy link
Member

@markcowl markcowl left a comment

Choose a reason for hiding this comment

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

Partial PR review, will complete

};

PSADServicePrincipal servicePrincipal = FilterServicePrincipals(options).FirstOrDefault();
var objId = objectId.ToString();
Copy link
Member

Choose a reason for hiding this comment

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

better to use a descriptive identifier, like objectIdString

using System.Management.Automation;

/// <summary>
/// This attribute will allow the user to autocomplete the -ResourceType parameter of a cmdlet with valid resource types
Copy link
Member

Choose a reason for hiding this comment

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

Can we split this into a separate PR? I want to make sure we get in as much of this as possible

instance.ClientFactory.GetCustomHandlers());
client.SubscriptionId = context.Subscription.Id;
// Retrieve only the first page of resource types to display to the user
var resourceTypes = client.Providers.ListAsync();
Copy link
Member

Choose a reason for hiding this comment

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

why only one page?

Copy link
Member Author

Choose a reason for hiding this comment

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

@markcowl looks like this was a copy-paste issue -- I changed this so it retrieves all pages


catch (Exception ex)
{
if (ex == null) { }
Copy link
Member

Choose a reason for hiding this comment

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

I think this check should also be in the ifdef

Copy link
Member Author

Choose a reason for hiding this comment

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

@markcowl this was modeled after the ResourceGroupCompleter, but I believe that it's here so that the release build won't fail due to an unused ex variable

instance.AuthenticationFactory.GetServiceClientCredentials(context, AzureEnvironment.Endpoint.ResourceManager),
instance.ClientFactory.GetCustomHandlers());
client.SubscriptionId = context.Subscription.Id;
// Retrieve only the first page of ResourceGroups to display to the user
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we can't pass in the parameter value through to the resource groups call to make the first page of results more effective

@@ -19,44 +19,31 @@
using System.Collections.Generic;
using System.Threading;

namespace Microsoft.Azure.Internal.Subscriptions.Models
namespace Microsoft.Azure.Commands.ResourceManager.Common.Paging
Copy link
Member

Choose a reason for hiding this comment

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

same comment - we cannot make breaking changes here. If we need to substantially redesign it, we should define a new class.

Copy link
Member Author

Choose a reason for hiding this comment

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

@markcowl this has been reverted

@@ -17,23 +17,36 @@
using System.Collections.Generic;
using System.Collections;

namespace Microsoft.Azure.Internal.Subscriptions.Models
Copy link
Member

Choose a reason for hiding this comment

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

same comment

Copy link
Member Author

Choose a reason for hiding this comment

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

@markcowl this has been reverted

@@ -113,7 +113,8 @@ public static string GetDisplayNameForADObject(string objectId, ActiveDirectoryC
}
else if (obj.Type.Equals("serviceprincipal", StringComparison.InvariantCultureIgnoreCase))
{
var servicePrincipal = adClient.FilterServicePrincipals(new ADObjectFilterOptions { Id = objectId }).FirstOrDefault();
var odataQuery = new Rest.Azure.OData.ODataQuery<Graph.RBAC.Version1_6.Models.ServicePrincipal>(s => s.ObjectId == objectId);
Copy link
Member

Choose a reason for hiding this comment

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

we should let the keyvault team look at these changes

@@ -607,6 +608,28 @@ public virtual List<PSResourceGroup> FilterResourceGroups(string name, Hashtable
resourceGroups.AddRange(listResult);
}

if (!string.IsNullOrEmpty(name))
Copy link
Member

Choose a reason for hiding this comment

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

ToDo: This would be really nice extracted out into a helper like:

IEnumerable<T> FilterByWildCard<T>(IEnumerable<T> source, Func<T, string> getKey, string parameterValue)

{
public class PSResource
{
public string Id { get; set; }
Copy link
Member

Choose a reason for hiding this comment

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

Need ResourceId for backward-compatible cmdlet piping, right?

@markcowl
Copy link
Member

@maddieclayton Can we get someone from KeyVaule to pass on the small changes here to KeyVault cmdlets?

Copy link
Member

@markcowl markcowl left a comment

Choose a reason for hiding this comment

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

ALso, we need a plan for test coverage

[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = ParameterSet.Explicit, HelpMessage = "The object id of the member.")]
[Parameter(Mandatory = true, ParameterSetName = ParameterSet.GroupObject, HelpMessage = "The object id of the member.")]
[ValidateNotNullOrEmpty]
public Guid MemberObjectId { get; set; }
Copy link
Member

Choose a reason for hiding this comment

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

For this to be parallel with other cmdlets using AD, we would want to have parameters to allow users to specify thee target group by name, and the user principals.

Also, for each of the parameters specifying things to add to the target group, including memberObjectId, I would make the parameter type an array, so we cna add multiple.


[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = ParameterSet.Explicit, HelpMessage = "The object id of the group to add the member to.")]
[ValidateNotNullOrEmpty]
public Guid GroupObjectId { get; set; }
Copy link
Member

Choose a reason for hiding this comment

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

I would change this to TargetGroupObjectId, and TargetGroupObject

[ValidateNotNullOrEmpty]
public Guid GroupObjectId { get; set; }
[Alias("Id", "GroupObjectId")]
Copy link
Member

Choose a reason for hiding this comment

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

We should consider having a group name parameter here, if it does not exist already

@@ -21,21 +23,32 @@ namespace Microsoft.Azure.Commands.ActiveDirectory
/// Gets AD service principal credentials.
/// </summary>
[Cmdlet(VerbsCommon.Get, "AzureRmADSpCredential", DefaultParameterSetName = ParameterSet.ObjectId), OutputType(typeof(PSADCredential))]
[Alias("Get-AzureRmADServicePrincipalCredential")]
Copy link
Member

Choose a reason for hiding this comment

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

Get-AzureRmADSpnCredential as well

Copy link
Member Author

Choose a reason for hiding this comment

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

@markcowl I think we agreed to skip this comment (I can add the alias if that's not the case)

SearchString = SearchString,
UPN = UserPrincipalName,
Id = ObjectId == Guid.Empty ? null : ObjectId.ToString(),
Paging = true,
Copy link
Member

Choose a reason for hiding this comment

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

what does the Paging option do here?

Copy link
Member Author

Choose a reason for hiding this comment

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

@markcowl it used to signal that the client should follow the nextPageLink, but that is now handled by GenericPageEnumerable, so this isn't necessarily needed (but I will keep it around 😀 )

[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = ParameterSet.SPNWithDisplayName, HelpMessage = "The display name for the application.")]
[Parameter(Mandatory = true, ParameterSetName = ParameterSet.InputObjectWithDisplayName, HelpMessage = "The display name for the application")]
[ValidateNotNullOrEmpty]
public string DisplayName { get; set; }
Copy link
Member

Choose a reason for hiding this comment

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

is this the only thins we can actually change?

Copy link
Member Author

@cormacpayne cormacpayne Apr 23, 2018

Choose a reason for hiding this comment

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

@markcowl added Homepage, IdentifierUri, KeyCredential and PasswordCredential parameters

@@ -81,7 +97,39 @@ Accept pipeline input: False
Accept wildcard characters: False
```

### -First
Gets the first N objects.
Copy link
Member

Choose a reason for hiding this comment

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

I would say The maximum number of objects to return


## DESCRIPTION
Updates an existing azure active directory application.
To update the credentials associated with this application, please use New-AzureRmADAppCredential cmdlet.
Copy link
Member

Choose a reason for hiding this comment

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

<nit>
.. please use the New-AzureRmADAppCredential...
</nit>

Get-AzureRmResource [-ResourceType <String>] [-ExtensionResourceType <String>] [-ExpandProperties]
[-IsCollection] [-ODataQuery <String>] [-ResourceGroupName <String>] [-ApiVersion <String>] [-Pre]
[-DefaultProfile <IAzureContextContainer>] [<CommonParameters>]
PS C:\> Get-AzureRmResource -Name testVM | ft
Copy link
Member

Choose a reason for hiding this comment

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

This output is | fl

{
try
{
Thread.Sleep(5000);
Copy link
Member

Choose a reason for hiding this comment

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

We should use our own TestMockSupport.Delay method so this doesn't take forever in playback

@dragav dragav requested a review from RandalliLama April 23, 2018 21:14
markcowl
markcowl previously approved these changes Apr 24, 2018
Copy link
Member

@markcowl markcowl left a comment

Choose a reason for hiding this comment

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

One yaml help issue, otherwise, lgtm

```

### -MemberUserPrincipalName
The UPN of the member(s) to remove.```yaml
Copy link
Member

Choose a reason for hiding this comment

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

yaml issue

@markcowl markcowl removed their assignment Apr 24, 2018
@RandalliLama
Copy link
Contributor

I'm taking a look. Will update in an hour.

@@ -59,7 +59,8 @@ public static PSADObject ToPSADObject(this AADObject obj)
DisplayName = obj.DisplayName,
Type = obj.ObjectType,
Id = new Guid(obj.ObjectId),
SecurityEnabled = obj.SecurityEnabled
SecurityEnabled = obj.SecurityEnabled,
MailNickname = obj.Mail
Copy link
Contributor

Choose a reason for hiding this comment

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

MailNickname = obj.Mail [](start = 20, length = 23)

for a group the mail will be always null,do we need this?
https://msdn.microsoft.com/en-us/library/azure/ad/graph/api/groups-operations

/// Updates an exisitng service principal.
/// </summary>
[Cmdlet(VerbsData.Update, "AzureRmADServicePrincipal", DefaultParameterSetName = ParameterSet.SpObjectIdWithDisplayName, SupportsShouldProcess = true), OutputType(typeof(PSADServicePrincipal))]
[Alias("Set-AzureRmADServicePrincipal")]
Copy link
Contributor

Choose a reason for hiding this comment

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

Set-AzureRmADServicePrincipa [](start = 12, length = 28)

why the change from Set to update?
isnt it confusing/inconsistent wrt other commandlets?
for some we have set and for others we have update

@maddieclayton maddieclayton changed the base branch from preview to release-6.0.0 April 26, 2018 21:37
…ve logic for Get-AzureRmResource into ProcessRecord
return result;
}

private IEnumerable<PSResource> FilterResourceByWildcard(IEnumerable<PSResource> result)
Copy link
Member

Choose a reason for hiding this comment

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

For the future, we should implement this once as a generic, and pass in a Function that gets the key we want to search

@markcowl
Copy link
Member

@cormacpayne
Copy link
Member Author

@cormacpayne
Copy link
Member Author

cormacpayne commented Apr 30, 2018

@@ -265,7 +265,8 @@ private string GetObjectIdBySpn(string spn)
if (!string.IsNullOrWhiteSpace(spn))
{
#if NETSTANDARD
var servicePrincipal = ActiveDirectoryClient.FilterServicePrincipals(new ADObjectFilterOptions() { SPN = spn }).SingleOrDefault();
var odataQuery = new Rest.Azure.OData.ODataQuery<Graph.RBAC.Version1_6.Models.ServicePrincipal>(s => s.ServicePrincipalNames.Contains(spn));
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this filter using a case insensitive compare like the one below on line 273? If not, is there a reason that it would not be using the same?

Copy link
Member Author

Choose a reason for hiding this comment

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

@RandalliLama the filter is case insensitive

RandalliLama
RandalliLama previously approved these changes Apr 30, 2018
@cormacpayne
Copy link
Member Author

@markcowl markcowl merged commit e590c75 into Azure:release-6.0.0 Apr 30, 2018
@cormacpayne cormacpayne deleted the resources-improvements branch May 2, 2018 23:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants