Hello community,

here is the log from the commit of package azure-cli-role for openSUSE:Factory 
checked in at 2018-05-13 16:03:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/azure-cli-role (Old)
 and      /work/SRC/openSUSE:Factory/.azure-cli-role.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "azure-cli-role"

Sun May 13 16:03:09 2018 rev:3 rq:600064 version:2.0.22

Changes:
--------
--- /work/SRC/openSUSE:Factory/azure-cli-role/azure-cli-role.changes    
2018-02-14 09:31:55.670815092 +0100
+++ /work/SRC/openSUSE:Factory/.azure-cli-role.new/azure-cli-role.changes       
2018-05-13 16:03:09.862492425 +0200
@@ -1,0 +2,8 @@
+Fri Apr 20 11:12:55 UTC 2018 - adrian.glaub...@suse.com
+
+- New upstream release
+  + Version 2.0.22
+- Move LICENSE.txt from %doc to %license section
+- Update Requires from setup.py
+
+-------------------------------------------------------------------

Old:
----
  azure-cli-role-2.0.17.tar.gz

New:
----
  azure-cli-role-2.0.22.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ azure-cli-role.spec ++++++
--- /var/tmp/diff_new_pack.0V0ymc/_old  2018-05-13 16:03:10.490469514 +0200
+++ /var/tmp/diff_new_pack.0V0ymc/_new  2018-05-13 16:03:10.494469368 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           azure-cli-role
-Version:        2.0.17
+Version:        2.0.22
 Release:        0
 Summary:        Microsoft Azure CLI 'role' Command Module for Role-Based 
Access Control (RBAC)
 License:        MIT
@@ -34,10 +34,12 @@
 Requires:       azure-cli-command-modules-nspkg
 Requires:       azure-cli-core
 Requires:       azure-cli-nspkg
-Requires:       python3-azure-graphrbac >= 0.31.0
+Requires:       python3-azure-graphrbac >= 0.40.0
 Requires:       python3-azure-keyvault >= 0.3.7
-Requires:       python3-azure-mgmt-authorization >= 0.30.0
+Requires:       python3-azure-mgmt-authorization >= 0.40.0
+Requires:       python3-azure-mgmt-monitor >= 0.5.0
 Requires:       python3-azure-nspkg
+Requires:       python3-pytz
 Conflicts:      azure-cli < 2.0.0
 
 BuildArch:      noarch
@@ -66,7 +68,8 @@
 
 %files
 %defattr(-,root,root,-)
-%doc HISTORY.rst LICENSE.txt README.rst
+%doc HISTORY.rst README.rst
+%license LICENSE.txt
 %{python3_sitelib}/azure/cli/command_modules/role
 %{python3_sitelib}/azure_cli_role-*.egg-info
 

++++++ azure-cli-role-2.0.17.tar.gz -> azure-cli-role-2.0.22.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-role-2.0.17/HISTORY.rst 
new/azure-cli-role-2.0.22/HISTORY.rst
--- old/azure-cli-role-2.0.17/HISTORY.rst       2018-01-12 18:25:22.000000000 
+0100
+++ new/azure-cli-role-2.0.22/HISTORY.rst       2018-04-06 19:33:13.000000000 
+0200
@@ -3,6 +3,27 @@
 Release History
 ===============
 
+2.0.22
+++++++
+
+* `sdist` is now compatible with wheel 0.31.0
+
+2.0.21
+++++++
+* graph: support required access configuration and native client 
+* rbac: ensure collection has less than 1000 ids on resolving graph objects
+* ad sp: new commands to manage credentials "az ad sp credential 
reset/list/delete"
+* role assignments: (breaking change)list/show output has "properties" removed 
to align with SDK
+* role definition: support `dataActions` and `notDataActions`
+
+2.0.20
+++++++
+* role assignments: expose "role assignment list-changelogs" for rbac audit 
+
+2.0.18
+++++++
+* ad app update: expose "--available-to-other-tenants"
+
 2.0.17
 ++++++
 * role assignment: expose --assignee-object-id to bypass graph query
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-role-2.0.17/PKG-INFO 
new/azure-cli-role-2.0.22/PKG-INFO
--- old/azure-cli-role-2.0.17/PKG-INFO  2018-01-12 18:25:50.000000000 +0100
+++ new/azure-cli-role-2.0.22/PKG-INFO  2018-04-06 19:33:56.000000000 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: azure-cli-role
-Version: 2.0.17
+Version: 2.0.22
 Summary: Microsoft Azure Command-Line Tools Role Command Module
 Home-page: https://github.com/Azure/azure-cli
 Author: Microsoft Corporation
 Author-email: azpy...@microsoft.com
 License: MIT
+Description-Content-Type: UNKNOWN
 Description: Microsoft Azure CLI 'role' Command Module for Role-Based Access 
Control (RBAC)
         
==============================================================================
         
@@ -20,6 +21,27 @@
         Release History
         ===============
         
+        2.0.22
+        ++++++
+        
+        * `sdist` is now compatible with wheel 0.31.0
+        
+        2.0.21
+        ++++++
+        * graph: support required access configuration and native client 
+        * rbac: ensure collection has less than 1000 ids on resolving graph 
objects
+        * ad sp: new commands to manage credentials "az ad sp credential 
reset/list/delete"
+        * role assignments: (breaking change)list/show output has "properties" 
removed to align with SDK
+        * role definition: support `dataActions` and `notDataActions`
+        
+        2.0.20
+        ++++++
+        * role assignments: expose "role assignment list-changelogs" for rbac 
audit 
+        
+        2.0.18
+        ++++++
+        * ad app update: expose "--available-to-other-tenants"
+        
         2.0.17
         ++++++
         * role assignment: expose --assignee-object-id to bypass graph query
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-role-2.0.17/azure/cli/command_modules/role/_help.py 
new/azure-cli-role-2.0.22/azure/cli/command_modules/role/_help.py
--- old/azure-cli-role-2.0.17/azure/cli/command_modules/role/_help.py   
2018-01-12 18:25:22.000000000 +0100
+++ new/azure-cli-role-2.0.22/azure/cli/command_modules/role/_help.py   
2018-04-06 19:33:13.000000000 +0200
@@ -57,8 +57,28 @@
           text: az ad sp create-for-rbac --keyvault MyVault --cert CertName
     """
 
+helps['ad sp credential'] = """
+    type: group
+    short-summary: manage a service principal's credentials.
+"""
+
+helps['ad sp credential list'] = """
+    type: command
+    short-summary: list a service principal's credentials.
+"""
+
+helps['ad sp credential delete'] = """
+    type: command
+    short-summary: delete a service principal's credential.
+"""
+
 helps['ad sp reset-credentials'] = """
     type: command
+    short-summary: (Deprecated, use "az ad sp credential reset")
+"""
+
+helps['ad sp credential reset'] = """
+    type: command
     short-summary: Reset a service principal credential.
     long-summary: Use upon expiration of the service principal's credentials, 
or in the event that login credentials are lost.
     parameters:
@@ -175,6 +195,12 @@
                         "Microsoft.Insights/alertRules/*",
                         "Microsoft.Support/*"
                     ],
+                    "DataActions": [
+                        
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/*"
+                    ],
+                    "NotDataActions": [
+                        
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write"
+                    ],
                     "AssignableScopes": 
["/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]
                 }'
         - name: Create a role from a file containing a JSON description.
@@ -215,6 +241,12 @@
                         "Microsoft.Insights/alertRules/*",
                         "Microsoft.Support/*"
                     ],
+                    "DataActions": [
+                        
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/*"
+                    ],
+                    "NotDataActions": [
+                        
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write"
+                    ],
                     "AssignableScopes": 
["/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]
                 }'
         - name: Create a role from a file containing a JSON description.
@@ -223,11 +255,25 @@
 """
 helps['ad'] = """
     type: group
-    short-summary: Synchronize on-premises directories and manage Azure Active 
Directory resources.
+    short-summary: Manage Azure Active Directory Graph entities needed for 
Role Based Access Control
 """
-helps['ad app'] = """
-    type: group
-    short-summary: Manage Azure Active Directory applications.
+helps['ad app create'] = """
+    type: command
+    short-summary: Create a web application, web API or native application
+    examples:
+        - name: Create a native application with delegated permission of 
"access the AAD directory as the signed-in user
+          text: |
+                az ad app create --display-name my-native --native-app 
--requiredResourceAccess @manifest.json
+                ("manifest.json" contains the following content)
+                [{
+                    "resourceAppId": "00000002-0000-0000-c000-000000000000",
+                    "resourceAccess": [
+                        {
+                            "id": "a42657d6-7f20-40e3-b6f0-cee03008a62a",
+                            "type": "Scope"
+                        }
+                   ]
+                }]
 """
 helps['ad group'] = """
     type: group
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-role-2.0.17/azure/cli/command_modules/role/_params.py 
new/azure-cli-role-2.0.22/azure/cli/command_modules/role/_params.py
--- old/azure-cli-role-2.0.17/azure/cli/command_modules/role/_params.py 
2018-01-12 18:25:22.000000000 +0100
+++ new/azure-cli-role-2.0.22/azure/cli/command_modules/role/_params.py 
2018-04-06 19:33:13.000000000 +0200
@@ -8,11 +8,11 @@
 from knack.arguments import CLIArgumentType
 
 from azure.cli.core.commands.parameters import get_enum_type, 
get_three_state_flag
+from azure.cli.core.commands.validators import validate_file_or_dict
 
 from azure.cli.command_modules.role._completers import 
get_role_definition_name_completion_list
 from azure.cli.command_modules.role._validators import validate_group, 
validate_member_id, validate_cert, VARIANT_GROUP_ID_ARGS
 
-
 name_arg_type = CLIArgumentType(options_list=('--name', '-n'), metavar='NAME')
 
 
@@ -24,8 +24,8 @@
         c.argument('display_name', help='the display name of the application')
         c.argument('homepage', help='the url where users can sign in and use 
your app.')
         c.argument('identifier', options_list=['--id'], help='identifier uri, 
application id, or object id')
-        c.argument('identifier_uris', nargs='+', help='space separated unique 
URIs that Azure AD can use for this app.')
-        c.argument('reply_urls', nargs='+', help='space separated URIs to 
which Azure AD will redirect in response to an OAuth 2.0 request. The value 
does not need to be a physical endpoint, but must be a valid URI.')
+        c.argument('identifier_uris', nargs='+', help='space-separated unique 
URIs that Azure AD can use for this app.')
+        c.argument('reply_urls', nargs='+', help='space-separated URIs to 
which Azure AD will redirect in response to an OAuth 2.0 request. The value 
does not need to be a physical endpoint, but must be a valid URI.')
         c.argument('start_date', help="Date or datetime at which credentials 
become valid(e.g. '2017-01-01T01:00:00+00:00' or '2017-01-01'). Default value 
is current time")
         c.argument('end_date', help="Date or datetime after which credentials 
expire(e.g. '2017-12-31T11:59:59+00:00' or '2017-12-31'). Default value is one 
year after current time")
         c.argument('available_to_other_tenants', help='the application can be 
used from any Azure AD tenants', arg_type=get_three_state_flag())
@@ -33,6 +33,14 @@
         # TODO: Update these with **enum_choice_list(...) when SDK supports 
proper enums
         c.argument('key_type', help='the type of the key credentials 
associated with the application', arg_type=get_enum_type(['AsymmetricX509Cert', 
'Password', 'Symmetric'], default='AsymmetricX509Cert'))
         c.argument('key_usage', help='the usage of the key credentials 
associated with the application.', arg_type=get_enum_type(['Sign', 'Verify'], 
default='Verify'))
+        c.argument('password', help="app password, aka 'client secret'")
+        c.argument('oauth2_allow_implicit_flow', 
arg_type=get_three_state_flag(), help='whether to allow implicit grant flow for 
OAuth2')
+        c.argument('required_resource_accesses', type=validate_file_or_dict,
+                   help="resource scopes and roles the application requires 
access to. Should be in manifest json format. See examples below for details")
+        c.argument('native_app', arg_type=get_three_state_flag(), help="an 
application which can be installed on a user's device or computer")
+
+    with self.argument_context('ad') as c:
+        c.ignore('additional_properties')
 
     with self.argument_context('ad sp') as c:
         c.argument('identifier', options_list=['--id'], help='service 
principal name, or object id')
@@ -46,7 +54,7 @@
         c.argument('skip_assignment', arg_type=get_three_state_flag(), 
help='do not create default assignment')
         c.argument('show_auth_for_sdk', options_list='--sdk-auth', 
help='output result in compatible with Azure SDK auth file', 
arg_type=get_three_state_flag())
 
-    for item in ['create-for-rbac', 'reset-credentials']:
+    for item in ['create-for-rbac', 'reset-credentials', 'ad sp']:
         with self.argument_context('ad sp {}'.format(item)) as c:
             c.argument('name', name_arg_type)
             c.argument('cert', arg_group='Credential', validator=validate_cert)
@@ -99,11 +107,17 @@
         c.argument('role', help='role name or id', 
completer=get_role_definition_name_completion_list)
         c.argument('show_all', options_list=['--all'], action='store_true', 
help='show all assignments under the current subscription')
         c.argument('include_inherited', action='store_true', help='include 
assignments applied on parent scopes')
+        c.argument('can_delegate', action='store_true', help='when set, the 
assignee will be able to create further role assignments to the same role')
         c.argument('assignee', help='represent a user, group, or service 
principal. supported format: object id, user sign-in name, or service principal 
name')
         c.argument('assignee_object_id', help="assignee's graph object id, 
such as the 'principal id' from a managed service identity. Use this instead of 
'--assignee' to bypass graph permission issues")
-        c.argument('ids', nargs='+', help='space separated role assignment 
ids')
+        c.argument('ids', nargs='+', help='space-separated role assignment 
ids')
         c.argument('include_classic_administrators', 
arg_type=get_three_state_flag(), help='list default role assignments for 
subscription classic administrators, aka co-admins')
 
+    time_help = ('The {} of the query in the format of %Y-%m-%dT%H:%M:%SZ, 
e.g. 2000-12-31T12:59:59Z. Defaults to {}')
+    with self.argument_context('role assignment list-changelogs') as c:
+        c.argument('start_time', help=time_help.format('start time', '1 Hour 
prior to the current time'))
+        c.argument('end_time', help=time_help.format('end time', 'the current 
time'))
+
     with self.argument_context('role definition') as c:
         c.argument('role_definition_id', options_list=['--name', '-n'], 
help='the role definition name')
         c.argument('custom_role_only', arg_type=get_three_state_flag(), 
help='custom roles only(vs. build-in ones)')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-role-2.0.17/azure/cli/command_modules/role/commands.py 
new/azure-cli-role-2.0.22/azure/cli/command_modules/role/commands.py
--- old/azure-cli-role-2.0.17/azure/cli/command_modules/role/commands.py        
2018-01-12 18:25:22.000000000 +0100
+++ new/azure-cli-role-2.0.22/azure/cli/command_modules/role/commands.py        
2018-04-06 19:33:13.000000000 +0200
@@ -15,14 +15,14 @@
 
 
 def transform_definition_list(result):
-    return [OrderedDict([('Name', r['properties']['roleName']), ('Type', 
r['properties']['type']),
-                         ('Description', r['properties']['description'])]) for 
r in result]
+    return [OrderedDict([('Name', r['roleName']), ('Type', r['type']),
+                         ('Description', r['description'])]) for r in result]
 
 
 def transform_assignment_list(result):
-    return [OrderedDict([('Principal', r['properties']['principalName']),
-                         ('Role', r['properties']['roleDefinitionName']),
-                         ('Scope', r['properties']['scope'])]) for r in result]
+    return [OrderedDict([('Principal', r['principalName']),
+                         ('Role', r['roleDefinitionName']),
+                         ('Scope', r['scope'])]) for r in result]
 
 
 def get_role_definition_op(operation_name):
@@ -73,6 +73,7 @@
         g.custom_command('delete', 'delete_role_assignments')
         g.custom_command('list', 'list_role_assignments', 
table_transformer=transform_assignment_list)
         g.custom_command('create', 'create_role_assignment')
+        g.custom_command('list-changelogs', 'list_role_assignment_change_logs')
 
     with self.command_group('ad app', 
client_factory=get_graph_client_applications, resource_type=PROFILE_TYPE, 
min_api='2017-03-10') as g:
         g.custom_command('create', 'create_application')
@@ -90,7 +91,10 @@
     # RBAC related
     with self.command_group('ad sp') as g:
         g.custom_command('create-for-rbac', 
'create_service_principal_for_rbac')
-        g.custom_command('reset-credentials', 
'reset_service_principal_credential')
+        g.custom_command('reset-credentials', 
'reset_service_principal_credential', deprecate_info='ad sp credential reset')
+        g.custom_command('credential reset', 
'reset_service_principal_credential')
+        g.custom_command('credential list', 
'list_service_principal_credentials')
+        g.custom_command('credential delete', 
'delete_service_principal_credential')
 
     with self.command_group('ad user', role_users_sdk) as g:
         g.command('delete', 'delete')
@@ -99,7 +103,7 @@
         g.custom_command('create', 'create_user', 
client_factory=get_graph_client_users, 
doc_string_source='azure.graphrbac.models#UserCreateParameters')
 
     with self.command_group('ad group', role_group_sdk) as g:
-        g.command('create', 'create')
+        g.custom_command('create', 'create_group', 
client_factory=get_graph_client_groups)
         g.command('delete', 'delete')
         g.command('show', 'get', exception_handler=empty_on_404)
         g.command('get-member-groups', 'get_member_groups')
@@ -109,4 +113,4 @@
         g.command('list', 'get_group_members')
         g.command('add', 'add_member')
         g.command('remove', 'remove_member')
-        g.command('check', 'is_member_of')
+        g.custom_command('check', 'check_group_membership', 
client_factory=get_graph_client_groups)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-role-2.0.17/azure/cli/command_modules/role/custom.py 
new/azure-cli-role-2.0.22/azure/cli/command_modules/role/custom.py
--- old/azure-cli-role-2.0.17/azure/cli/command_modules/role/custom.py  
2018-01-12 18:25:22.000000000 +0100
+++ new/azure-cli-role-2.0.22/azure/cli/command_modules/role/custom.py  
2018-04-06 19:33:13.000000000 +0200
@@ -6,6 +6,7 @@
 from __future__ import print_function
 
 import datetime
+import json
 import re
 import os
 import uuid
@@ -20,16 +21,12 @@
 
 from azure.cli.core.util import get_file_json, shell_safe_json_parse
 
-from azure.mgmt.authorization.models import (RoleAssignmentProperties, 
Permission, RoleDefinition,
-                                             RoleDefinitionProperties)
+from azure.mgmt.authorization.models import RoleAssignmentCreateParameters, 
Permission, RoleDefinition
 
-from azure.graphrbac.models import (ApplicationCreateParameters,
-                                    ApplicationUpdateParameters,
-                                    PasswordCredential,
-                                    KeyCredential,
-                                    UserCreateParameters,
-                                    PasswordProfile,
-                                    ServicePrincipalCreateParameters)
+from azure.graphrbac.models import (ApplicationCreateParameters, 
ApplicationUpdateParameters, PasswordCredential,
+                                    KeyCredential, UserCreateParameters, 
PasswordProfile,
+                                    ServicePrincipalCreateParameters, 
RequiredResourceAccess,
+                                    ResourceAccess, GroupCreateParameters, 
CheckGroupMembershipParameters)
 
 from ._client_factory import _auth_client_factory, _graph_client_factory
 
@@ -81,7 +78,7 @@
             raise CLIError('Please provide the unique logic name of an 
existing role')
         role_definition['name'] = matched[0].name
         # ensure correct logical name and guid name. For update we accept both
-        role_name = matched[0].properties.role_name
+        role_name = matched[0].role_name
         role_id = matched[0].name
     else:
         role_id = _gen_guid()
@@ -90,18 +87,19 @@
         raise CLIError("please provide 'assignableScopes'")
 
     permission = Permission(actions=role_definition.get('actions', None),
-                            not_actions=role_definition.get('notActions', 
None))
-    properties = RoleDefinitionProperties(role_name=role_name,
-                                          
description=role_definition.get('description', None),
-                                          type=_CUSTOM_RULE,
-                                          
assignable_scopes=role_definition['assignableScopes'],
-                                          permissions=[permission])
-
-    definition = RoleDefinition(name=role_id, properties=properties)
+                            not_actions=role_definition.get('notActions', 
None),
+                            data_actions=role_definition.get('dataActions', 
None),
+                            
not_data_actions=role_definition.get('notDataActions', None))
+
+    role_definition = RoleDefinition(role_name=role_name,
+                                     
description=role_definition.get('description', None),
+                                     role_type=_CUSTOM_RULE,
+                                     
assignable_scopes=role_definition['assignableScopes'],
+                                     permissions=[permission])
 
     return definitions_client.create_or_update(role_definition_id=role_id,
-                                               
scope=properties.assignable_scopes[0],
-                                               role_definition=definition)
+                                               
scope=role_definition.assignable_scopes[0],
+                                               role_definition=role_definition)
 
 
 def delete_role_definition(cmd, name, resource_group_name=None, scope=None,
@@ -117,17 +115,18 @@
 def _search_role_definitions(definitions_client, name, scope, 
custom_role_only=False):
     roles = list(definitions_client.list(scope))
     if name:
-        roles = [r for r in roles if r.name == name or r.properties.role_name 
== name]
+        roles = [r for r in roles if r.name == name or r.role_name == name]
     if custom_role_only:
-        roles = [r for r in roles if r.properties.type == _CUSTOM_RULE]
+        roles = [r for r in roles if r.role_type == _CUSTOM_RULE]
     return roles
 
 
-def create_role_assignment(cmd, role, assignee=None, assignee_object_id=None, 
resource_group_name=None, scope=None):
+def create_role_assignment(cmd, role, assignee=None, assignee_object_id=None, 
resource_group_name=None,
+                           scope=None):
     if bool(assignee) == bool(assignee_object_id):
         raise CLIError('usage error: --assignee STRING | --assignee-object-id 
GUID')
-    return _create_role_assignment(cmd.cli_ctx, role, assignee or 
assignee_object_id,
-                                   resource_group_name, scope, 
resolve_assignee=(not assignee_object_id))
+    return _create_role_assignment(cmd.cli_ctx, role, assignee or 
assignee_object_id, resource_group_name, scope,
+                                   resolve_assignee=(not assignee_object_id))
 
 
 def _create_role_assignment(cli_ctx, role, assignee, resource_group_name=None, 
scope=None,
@@ -141,10 +140,11 @@
 
     role_id = _resolve_role_id(role, scope, definitions_client)
     object_id = _resolve_object_id(cli_ctx, assignee) if resolve_assignee else 
assignee
-    properties = RoleAssignmentProperties(role_id, object_id)
+    parameters = RoleAssignmentCreateParameters(role_definition_id=role_id, 
principal_id=object_id)
     assignment_name = _gen_guid()
     custom_headers = None
-    return assignments_client.create(scope, assignment_name, properties,
+    return assignments_client.create(scope=scope, 
role_assignment_name=assignment_name,
+                                     parameters=parameters,
                                      custom_headers=custom_headers)
 
 
@@ -184,22 +184,22 @@
     # 2. fill in role names
     role_defs = list(definitions_client.list(
         scope=scope or ('/subscriptions/' + 
definitions_client.config.subscription_id)))
-    role_dics = {i.id: i.properties.role_name for i in role_defs}
+    role_dics = {i.id: i.role_name for i in role_defs}
     for i in results:
-        if role_dics.get(i['properties']['roleDefinitionId']):
-            i['properties']['roleDefinitionName'] = 
role_dics[i['properties']['roleDefinitionId']]
+        if role_dics.get(i['roleDefinitionId']):
+            i['roleDefinitionName'] = role_dics[i['roleDefinitionId']]
 
     # fill in principal names
-    principal_ids = set(i['properties']['principalId'] for i in results if 
i['properties']['principalId'])
+    principal_ids = set(i['principalId'] for i in results if i['principalId'])
     if principal_ids:
         try:
             principals = _get_object_stubs(graph_client, principal_ids)
             principal_dics = {i.object_id: _get_displayable_name(i) for i in 
principals}
 
-            for i in [r for r in results if not 
r['properties'].get('principalName')]:
-                i['properties']['principalName'] = ''
-                if principal_dics.get(i['properties']['principalId']):
-                    i['properties']['principalName'] = 
principal_dics[i['properties']['principalId']]
+            for i in [r for r in results if not r.get('principalName')]:
+                i['principalName'] = ''
+                if principal_dics.get(i['principalId']):
+                    i['principalName'] = principal_dics[i['principalId']]
         except (CloudError, GraphErrorException) as ex:
             # failure on resolving principal due to graph permission should 
not fail the whole thing
             logger.info("Failed to resolve graph object information per error 
'%s'", ex)
@@ -207,41 +207,173 @@
     return results
 
 
+def _get_assignment_events(cli_ctx, start_time=None, end_time=None):
+    from azure.mgmt.monitor import MonitorManagementClient
+    from azure.cli.core.commands.client_factory import get_mgmt_service_client
+    client = get_mgmt_service_client(cli_ctx, MonitorManagementClient)
+    DATE_TIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
+    if end_time:
+        try:
+            end_time = datetime.datetime.strptime(end_time, DATE_TIME_FORMAT)
+        except ValueError:
+            raise CLIError("Input '{}' is not valid datetime. Valid example: 
2000-12-31T12:59:59Z".format(end_time))
+    else:
+        end_time = datetime.datetime.utcnow()
+
+    if start_time:
+        try:
+            start_time = datetime.datetime.strptime(start_time, 
DATE_TIME_FORMAT)
+            if start_time >= end_time:
+                raise CLIError("Start time cannot be later than end time.")
+        except ValueError:
+            raise CLIError("Input '{}' is not valid datetime. Valid example: 
2000-12-31T12:59:59Z".format(start_time))
+    else:
+        start_time = end_time - datetime.timedelta(hours=1)
+
+    time_filter = 'eventTimestamp ge {} and eventTimestamp le 
{}'.format(start_time.strftime('%Y-%m-%dT%H:%M:%SZ'),
+                                                                         
end_time.strftime('%Y-%m-%dT%H:%M:%SZ'))
+
+    # set time range filter
+    odata_filters = 'resourceProvider eq Microsoft.Authorization and 
{}'.format(time_filter)
+
+    activity_log = list(client.activity_logs.list(filter=odata_filters))
+    start_events, end_events, offline_events = {}, {}, []
+
+    for l in activity_log:
+        if l.http_request:
+            if l.status.value == 'Started':
+                start_events[l.operation_id] = l
+            else:
+                end_events[l.operation_id] = l
+        elif l.event_name and l.event_name.value.lower() == 
'classicadministrators':
+            offline_events.append(l)
+    return start_events, end_events, offline_events, client
+
+
+# A custom command around 'monitoring' events to produce understandable output 
for RBAC audit, a common scenario.
+def list_role_assignment_change_logs(cmd, start_time=None, end_time=None):
+    # pylint: disable=too-many-nested-blocks, too-many-statements
+    result = []
+    start_events, end_events, offline_events, client = 
_get_assignment_events(cmd.cli_ctx, start_time, end_time)
+    role_defs = {d.id: [d.role_name, d.id.split('/')[-1]] for d in 
list_role_definitions(cmd)}
+
+    for op_id in start_events:
+        e = end_events.get(op_id, None)
+        if not e:
+            continue
+
+        entry = {}
+        op = e.operation_name and e.operation_name.value
+        if (op.lower().startswith('microsoft.authorization/roleassignments') 
and e.status.value == 'Succeeded'):
+            s, payload = start_events[op_id], None
+            entry = dict.fromkeys(
+                ['principalId', 'principalName', 'scope', 'scopeName', 
'scopeType', 'roleDefinitionId', 'roleName'],
+                None)
+            entry['timestamp'], entry['caller'] = e.event_timestamp, s.caller
+
+            if s.http_request:
+                if s.http_request.method == 'PUT':
+                    # 'requestbody' has a wrong camel-case. Should be 
'requestBody'
+                    payload = s.properties and s.properties.get('requestbody')
+                    entry['action'] = 'Granted'
+                    entry['scope'] = e.authorization.scope
+                elif s.http_request.method == 'DELETE':
+                    payload = e.properties and e.properties.get('responseBody')
+                    entry['action'] = 'Revoked'
+            if payload:
+                try:
+                    payload = json.loads(payload)
+                except ValueError:
+                    pass
+                if payload:
+                    payload = payload['properties']
+                    entry['principalId'] = payload['principalId']
+                    if not entry['scope']:
+                        entry['scope'] = payload['scope']
+                    if entry['scope']:
+                        index = 
entry['scope'].lower().find('/providers/microsoft.authorization')
+                        if index != -1:
+                            entry['scope'] = entry['scope'][:index]
+                        parts = list(filter(None, entry['scope'].split('/')))
+                        entry['scopeName'] = parts[-1]
+                        if len(parts) < 3:
+                            entry['scopeType'] = 'Subscription'
+                        elif len(parts) < 5:
+                            entry['scopeType'] = 'Resource group'
+                        else:
+                            entry['scopeType'] = 'Resource'
+
+                    entry['roleDefinitionId'] = 
role_defs[payload['roleDefinitionId']][1]
+                    entry['roleName'] = 
role_defs[payload['roleDefinitionId']][0]
+            result.append(entry)
+
+    # Fill in logical user/sp names as guid principal-id not readable
+    principal_ids = set([x['principalId'] for x in result if x['principalId']])
+    if principal_ids:
+        graph_client = _graph_client_factory(cmd.cli_ctx)
+        stubs = _get_object_stubs(graph_client, principal_ids)
+        principal_dics = {i.object_id: _get_displayable_name(i) for i in stubs}
+        if principal_dics:
+            for e in result:
+                e['principalName'] = principal_dics.get(e['principalId'], None)
+
+    offline_events = [x for x in offline_events if (x.status and 
x.status.value == 'Succeeded' and x.operation_name and
+                                                    
x.operation_name.value.lower().startswith(
+                                                        
'microsoft.authorization/classicadministrators'))]
+    for e in offline_events:
+        entry = {
+            'timestamp': e.event_timestamp,
+            'caller': 'Subscription Admin',
+            'roleDefinitionId': None,
+            'principalId': None,
+            'principalType': 'User',
+            'scope': '/subscriptions/' + client.config.subscription_id,
+            'scopeType': 'Subscription',
+            'scopeName': client.config.subscription_id,
+        }
+        if e.properties:
+            entry['principalName'] = e.properties.get('adminEmail')
+            entry['roleName'] = e.properties.get('adminType')
+        result.append(entry)
+
+    return result
+
+
 def _backfill_assignments_for_co_admins(cli_ctx, auth_client, assignee=None):
-    co_admins = auth_client.classic_administrators.list('2015-06-01')  # known 
swagger bug on api-version handling
-    co_admins = [x for x in co_admins if x.properties.email_address]
+    co_admins = auth_client.classic_administrators.list()  # known swagger bug 
on api-version handling
+    co_admins = [x for x in co_admins if x.email_address]
     graph_client = _graph_client_factory(cli_ctx)
     if assignee:  # apply assignee filter if applicable
         if _is_guid(assignee):
-            result = _get_object_stubs(graph_client, [assignee])
-            if not result:
-                return []
-            assignee = _get_displayable_name(result[0]).lower()
-
-        co_admins = [x for x in co_admins if assignee == 
x.properties.email_address.lower()]
+            try:
+                result = _get_object_stubs(graph_client, [assignee])
+                if not result:
+                    return []
+                assignee = _get_displayable_name(result[0]).lower()
+            except ValueError:
+                pass
+        co_admins = [x for x in co_admins if assignee == 
x.email_address.lower()]
 
     if not co_admins:
         return []
 
     result, users = [], []
     for i in range(0, len(co_admins), 10):  # graph allows up to 10 query 
filters, so split into chunks here
-        upn_queries = ["userPrincipalName eq 
'{}'".format(x.properties.email_address) for x in co_admins[i:i + 10]]
+        upn_queries = ["userPrincipalName eq '{}'".format(x.email_address) for 
x in co_admins[i:i + 10]]
         temp = list(list_users(graph_client.users, query_filter=' or 
'.join(upn_queries)))
         users += temp
     upns = {u.user_principal_name: u.object_id for u in users}
     for admin in co_admins:
         na_text = 'NA(classic admins)'
-        email = admin.properties.email_address
+        email = admin.email_address
         result.append({
             'id': na_text,
             'name': na_text,
-            'properties': {
-                'principalId': upns.get(email),
-                'principalName': email,
-                'roleDefinitionName': admin.properties.role,
-                'roleDefinitionId': 'NA(classic admin role)',
-                'scope': '/subscriptions/' + auth_client.config.subscription_id
-            }
+            'principalId': upns.get(email),
+            'principalName': email,
+            'roleDefinitionName': admin.role,
+            'roleDefinitionId': 'NA(classic admin role)',
+            'scope': '/subscriptions/' + auth_client.config.subscription_id
         })
     return result
 
@@ -301,13 +433,13 @@
     if assignments:
         assignments = [a for a in assignments if (
             not scope or
-            include_inherited and re.match(a.properties.scope, scope, re.I) or
-            a.properties.scope.lower() == scope.lower()
+            include_inherited and re.match(a.scope, scope, re.I) or
+            a.scope.lower() == scope.lower()
         )]
 
         if role:
             role_id = _resolve_role_id(role, scope, definitions_client)
-            assignments = [i for i in assignments if 
i.properties.role_definition_id == role_id]
+            assignments = [i for i in assignments if i.role_definition_id == 
role_id]
 
     return assignments
 
@@ -394,10 +526,20 @@
                                  display_name=display_name, 
mail_nickname=mail_nickname,
                                  immutable_id=immutable_id,
                                  password_profile=PasswordProfile(
-                                     password, 
force_change_password_next_login))
+                                     password=password,
+                                     
force_change_password_next_login=force_change_password_next_login))
     return client.create(param)
 
 
+def create_group(client, display_name, mail_nickname):
+    return client.create(GroupCreateParameters(display_name=display_name, 
mail_nickname=mail_nickname))
+
+
+def check_group_membership(cmd, client, group_id, member_object_id):  # 
pylint: disable=unused-argument
+    return 
client.is_member_of(CheckGroupMembershipParameters(group_id=group_id,
+                                                              
member_id=member_object_id))
+
+
 def list_groups(client, display_name=None, query_filter=None):
     '''
     list groups in the directory
@@ -410,23 +552,36 @@
     return client.list(filter=(' and ').join(sub_filters))
 
 
-def create_application(client, display_name, homepage, identifier_uris,
+def create_application(client, display_name, homepage=None, 
identifier_uris=None,
                        available_to_other_tenants=False, password=None, 
reply_urls=None,
-                       key_value=None, key_type=None, key_usage=None, 
start_date=None,
-                       end_date=None):
-    password_creds, key_creds = _build_application_creds(password, key_value, 
key_type,
-                                                         key_usage, 
start_date, end_date)
-
-    app_create_param = ApplicationCreateParameters(available_to_other_tenants,
-                                                   display_name,
-                                                   identifier_uris,
-                                                   homepage=homepage,
-                                                   reply_urls=reply_urls,
-                                                   key_credentials=key_creds,
-                                                   
password_credentials=password_creds)
+                       key_value=None, key_type=None, key_usage=None, 
start_date=None, end_date=None,
+                       oauth2_allow_implicit_flow=None, 
required_resource_accesses=None, native_app=None):
+    key_creds, password_creds, required_accesses = None, None, None
+    if native_app:
+        if identifier_uris:
+            raise CLIError("'--identifier-uris' is not required for creating a 
native application")
+        identifier_uris = ['http://{}'.format(_gen_guid())]  # we will create 
a temporary one and remove it later
+    else:
+        if not identifier_uris:
+            raise CLIError("'--identifier-uris' is required for creating an 
application")
+        password_creds, key_creds = _build_application_creds(password, 
key_value, key_type,
+                                                             key_usage, 
start_date, end_date)
+
+    if required_resource_accesses:
+        required_accesses = 
_build_application_accesses(required_resource_accesses)
+
+    app_patch_param = 
ApplicationCreateParameters(available_to_other_tenants=available_to_other_tenants,
+                                                  display_name=display_name,
+                                                  
identifier_uris=identifier_uris,
+                                                  homepage=homepage,
+                                                  reply_urls=reply_urls,
+                                                  key_credentials=key_creds,
+                                                  
password_credentials=password_creds,
+                                                  
oauth2_allow_implicit_flow=oauth2_allow_implicit_flow,
+                                                  
required_resource_access=required_accesses)
 
     try:
-        return client.create(app_create_param)
+        result = client.create(app_patch_param)
     except GraphErrorException as ex:
         if 'insufficient privileges' in str(ex).lower():
             link = 
'https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal'
  # pylint: disable=line-too-long
@@ -434,23 +589,57 @@
                            "For how to configure, please refer '{}'. Original 
error: {}".format(link, ex))
         raise
 
+    if native_app:
+        # AAD graph doesn't have the API to create a native app, aka public 
client, the recommended hack is
+        # to create a web app first, then convert to a native one
+        # pylint: disable=protected-access
+        if 'public_client' not in ApplicationUpdateParameters._attribute_map:
+            ApplicationUpdateParameters._attribute_map['public_client'] = 
{'key': 'publicClient', 'type': 'bool'}
+        app_patch_param = ApplicationUpdateParameters(identifier_uris=[])
+        setattr(app_patch_param, 'public_client', True)
+        client.patch(result.object_id, app_patch_param)
+        result = client.get(result.object_id)
+
+    return result
+
 
 def update_application(client, identifier, display_name=None, homepage=None,
                        identifier_uris=None, password=None, reply_urls=None, 
key_value=None,
-                       key_type=None, key_usage=None, start_date=None, 
end_date=None):
+                       key_type=None, key_usage=None, start_date=None, 
end_date=None, available_to_other_tenants=None,
+                       oauth2_allow_implicit_flow=None, 
required_resource_accesses=None):
     object_id = _resolve_application(client, identifier)
-    password_creds, key_creds = _build_application_creds(password, key_value, 
key_type,
-                                                         key_usage, 
start_date, end_date)
+
+    password_creds, key_creds, required_accesses = None, None, None
+    if any([key_value, key_type, key_usage, start_date, end_date]):
+        password_creds, key_creds = _build_application_creds(password, 
key_value, key_type,
+                                                             key_usage, 
start_date, end_date)
+
+    if required_resource_accesses:
+        required_accesses = 
_build_application_accesses(required_resource_accesses)
 
     app_patch_param = ApplicationUpdateParameters(display_name=display_name,
                                                   homepage=homepage,
                                                   
identifier_uris=identifier_uris,
                                                   reply_urls=reply_urls,
                                                   key_credentials=key_creds,
-                                                  
password_credentials=password_creds)
+                                                  
password_credentials=password_creds,
+                                                  
available_to_other_tenants=available_to_other_tenants,
+                                                  
required_resource_access=required_accesses,
+                                                  
oauth2_allow_implicit_flow=oauth2_allow_implicit_flow)
     return client.patch(object_id, app_patch_param)
 
 
+def _build_application_accesses(required_resource_accesses):
+    required_accesses = None
+    for x in required_resource_accesses:
+        accesses = [ResourceAccess(id=y['id'], type=y['type']) for y in 
x['resourceAccess']]
+        if required_accesses is None:
+            required_accesses = []
+        
required_accesses.append(RequiredResourceAccess(resource_app_id=x['resourceAppId'],
+                                                        
resource_access=accesses))
+    return required_accesses
+
+
 def show_application(client, identifier):
     object_id = _resolve_application(client, identifier)
     return client.get(object_id)
@@ -494,10 +683,12 @@
     password_creds = None
     key_creds = None
     if password:
-        password_creds = [PasswordCredential(start_date, end_date, 
str(_gen_guid()), password)]
+        password_creds = [PasswordCredential(start_date=start_date, 
end_date=end_date,
+                                             key_id=str(_gen_guid()), 
value=password)]
     elif key_value:
-        key_creds = [KeyCredential(start_date, end_date, key_value, 
str(_gen_guid()),
-                                   key_usage, key_type)]
+        key_creds = [KeyCredential(start_date=start_date, end_date=end_date,
+                                   key_id=str(_gen_guid()), value=key_value,
+                                   usage=key_usage, type=key_type)]
 
     return (password_creds, key_creds)
 
@@ -532,25 +723,86 @@
 
 def delete_service_principal(cmd, identifier):
     client = _graph_client_factory(cmd.cli_ctx)
-    sp = 
client.service_principals.get(_resolve_service_principal(client.service_principals,
 identifier))
+    sp_object_id = _resolve_service_principal(client.service_principals, 
identifier)
+    app_object_id = _get_app_object_id_from_sp_object_id(client, sp_object_id)
+
+    assignments = list_role_assignments(cmd, assignee=identifier, 
show_all=True)
+    if assignments:
+        logger.warning('Removing role assignments')
+        delete_role_assignments(cmd, [a['id'] for a in assignments])
+
+    if app_object_id:  # delete the application, and AAD service will 
automatically clean up the SP
+        client.applications.delete(app_object_id)
+    else:
+        client.service_principals.delete(sp_object_id)
+
+
+def _get_app_object_id_from_sp_object_id(client, sp_object_id):
+    sp = client.service_principals.get(sp_object_id)
     app_object_id = None
 
-    # see whether we need to delete the application if it is in the same tenant
     if sp.service_principal_names:
         result = list(client.applications.list(
             filter="identifierUris/any(s:s eq 
'{}')".format(sp.service_principal_names[0])))
         if result:
             app_object_id = result[0].object_id
+    return app_object_id
 
-    assignments = list_role_assignments(cmd, assignee=identifier, 
show_all=True)
-    if assignments:
-        logger.warning('Removing role assignments')
-        delete_role_assignments(cmd, [a['id'] for a in assignments])
 
-    if app_object_id:  # delete the application, and AAD service will 
automatically clean up the SP
-        client.applications.delete(app_object_id)
+def list_service_principal_credentials(cmd, identifier, cert=False):
+    client = _graph_client_factory(cmd.cli_ctx)
+    sp_object_id = _resolve_service_principal(client.service_principals, 
identifier)
+    app_object_id = _get_app_object_id_from_sp_object_id(client, sp_object_id)
+    sp_creds, app_creds = [], []
+    if cert:
+        sp_creds = 
list(client.service_principals.list_key_credentials(sp_object_id))
+        if app_object_id:
+            app_creds = 
list(client.applications.list_key_credentials(app_object_id))
     else:
-        client.service_principals.delete(sp.object_id)
+        sp_creds = 
list(client.service_principals.list_password_credentials(sp_object_id))
+        if app_object_id:
+            app_creds = 
list(client.applications.list_password_credentials(app_object_id))
+
+    for x in sp_creds:
+        setattr(x, 'source', 'ServicePrincipal')
+    for x in app_creds:
+        setattr(x, 'source', 'Application')
+    return app_creds + sp_creds
+
+
+def delete_service_principal_credential(cmd, identifier, key_id, cert=False):
+    client = _graph_client_factory(cmd.cli_ctx)
+    sp_object_id = _resolve_service_principal(client.service_principals, 
identifier)
+    if cert:
+        result = 
list(client.service_principals.list_key_credentials(sp_object_id))
+    else:
+        result = 
list(client.service_principals.list_password_credentials(sp_object_id))
+
+    to_delete = next((x for x in result if x.key_id == key_id), None)
+
+    # we will try to delete the creds at service principal level, if not 
found, we try application level
+
+    if to_delete:
+        result.remove(to_delete)
+        if cert:
+            return 
client.service_principals.update_key_credentials(sp_object_id, result)
+        return 
client.service_principals.update_password_credentials(sp_object_id, result)
+    else:
+        app_object_id = _get_app_object_id_from_sp_object_id(client, 
sp_object_id)
+        if app_object_id:
+            if cert:
+                result = 
list(client.applications.list_key_credentials(app_object_id))
+            else:
+                result = 
list(client.applications.list_password_credentials(app_object_id))
+            to_delete = next((x for x in result if x.key_id == key_id), None)
+            if to_delete:
+                result.remove(to_delete)
+                if cert:
+                    return 
client.applications.update_key_credentials(app_object_id, result)
+                return 
client.applications.update_password_credentials(app_object_id, result)
+
+    raise CLIError("'{}' doesn't exist in the service principal of '{}' or 
associated application".format(
+        key_id, identifier))
 
 
 def _resolve_service_principal(client, identifier):
@@ -718,7 +970,6 @@
                     raise
 
     if show_auth_for_sdk:
-        import json
         from azure.cli.core._profile import Profile
         profile = Profile(cli_ctx=cmd.cli_ctx)
         result = profile.get_sp_auth_info(scopes[0].split('/')[2] if scopes 
else None,
@@ -1001,12 +1252,16 @@
     return False
 
 
+def _get_object_stubs(graph_client, assignees):
+    from azure.graphrbac.models import GetObjectsParameters
+    result = []
+    assignees = list(assignees)  # callers could pass in a set
+    for i in range(0, len(assignees), 1000):
+        params = 
GetObjectsParameters(include_directory_object_references=True, 
object_ids=assignees[i:i + 1000])
+        result += list(graph_client.objects.get_objects_by_object_ids(params))
+    return result
+
+
 # for injecting test seams to produce predicatable role assignment id for 
playback
 def _gen_guid():
     return uuid.uuid4()
-
-
-def _get_object_stubs(graph_client, assignees):
-    from azure.graphrbac.models import GetObjectsParameters
-    params = GetObjectsParameters(include_directory_object_references=True, 
object_ids=assignees)
-    return list(graph_client.objects.get_objects_by_object_ids(params))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-role-2.0.17/azure_cli_role.egg-info/PKG-INFO 
new/azure-cli-role-2.0.22/azure_cli_role.egg-info/PKG-INFO
--- old/azure-cli-role-2.0.17/azure_cli_role.egg-info/PKG-INFO  2018-01-12 
18:25:50.000000000 +0100
+++ new/azure-cli-role-2.0.22/azure_cli_role.egg-info/PKG-INFO  2018-04-06 
19:33:56.000000000 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: azure-cli-role
-Version: 2.0.17
+Version: 2.0.22
 Summary: Microsoft Azure Command-Line Tools Role Command Module
 Home-page: https://github.com/Azure/azure-cli
 Author: Microsoft Corporation
 Author-email: azpy...@microsoft.com
 License: MIT
+Description-Content-Type: UNKNOWN
 Description: Microsoft Azure CLI 'role' Command Module for Role-Based Access 
Control (RBAC)
         
==============================================================================
         
@@ -20,6 +21,27 @@
         Release History
         ===============
         
+        2.0.22
+        ++++++
+        
+        * `sdist` is now compatible with wheel 0.31.0
+        
+        2.0.21
+        ++++++
+        * graph: support required access configuration and native client 
+        * rbac: ensure collection has less than 1000 ids on resolving graph 
objects
+        * ad sp: new commands to manage credentials "az ad sp credential 
reset/list/delete"
+        * role assignments: (breaking change)list/show output has "properties" 
removed to align with SDK
+        * role definition: support `dataActions` and `notDataActions`
+        
+        2.0.20
+        ++++++
+        * role assignments: expose "role assignment list-changelogs" for rbac 
audit 
+        
+        2.0.18
+        ++++++
+        * ad app update: expose "--available-to-other-tenants"
+        
         2.0.17
         ++++++
         * role assignment: expose --assignee-object-id to bypass graph query
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-cli-role-2.0.17/azure_cli_role.egg-info/requires.txt 
new/azure-cli-role-2.0.22/azure_cli_role.egg-info/requires.txt
--- old/azure-cli-role-2.0.17/azure_cli_role.egg-info/requires.txt      
2018-01-12 18:25:50.000000000 +0100
+++ new/azure-cli-role-2.0.22/azure_cli_role.egg-info/requires.txt      
2018-04-06 19:33:56.000000000 +0200
@@ -1,5 +1,6 @@
 azure-cli-core
-azure-mgmt-authorization==0.30.0
-azure-graphrbac==0.31.0
+azure-mgmt-authorization==0.40.0
+azure-mgmt-monitor==0.5.0
+azure-graphrbac==0.40.0
 azure-keyvault==0.3.7
 pytz
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-cli-role-2.0.17/setup.py 
new/azure-cli-role-2.0.22/setup.py
--- old/azure-cli-role-2.0.17/setup.py  2018-01-12 18:25:22.000000000 +0100
+++ new/azure-cli-role-2.0.22/setup.py  2018-04-06 19:33:14.000000000 +0200
@@ -14,7 +14,7 @@
     logger.warn("Wheel is not available, disabling bdist_wheel hook")
     cmdclass = {}
 
-VERSION = "2.0.17"
+VERSION = "2.0.22"
 CLASSIFIERS = [
     'Development Status :: 5 - Production/Stable',
     'Intended Audience :: Developers',
@@ -31,8 +31,9 @@
 
 DEPENDENCIES = [
     'azure-cli-core',
-    'azure-mgmt-authorization==0.30.0',
-    'azure-graphrbac==0.31.0',
+    'azure-mgmt-authorization==0.40.0',
+    'azure-mgmt-monitor==0.5.0',
+    'azure-graphrbac==0.40.0',
     'azure-keyvault==0.3.7',
     'pytz'
 ]


Reply via email to