Skip to content
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
3 changes: 1 addition & 2 deletions azure-cli.pyproj
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@
<Compile Include="command_modules\azure-cli-role\azure\cli\command_modules\role\_help.py">
<SubType>Code</SubType>
</Compile>
<Compile Include="command_modules\azure-cli-role\azure\cli\command_modules\role\tests\test_graph.py" />
<Compile Include="command_modules\azure-cli-storage\azure\cli\command_modules\storage\_command_type.py" />
<Compile Include="command_modules\azure-cli-storage\azure\cli\command_modules\storage\_factory.py" />
<Compile Include="command_modules\azure-cli-storage\azure\cli\command_modules\storage\_help.py">
Expand Down Expand Up @@ -612,9 +613,7 @@
<Content Include="command_modules\azure-cli-resource\azure\cli\command_modules\resource\tests\simple_deploy.json" />
<Content Include="command_modules\azure-cli-resource\azure\cli\command_modules\resource\tests\simple_deploy_parameters.json" />
<Content Include="command_modules\azure-cli-resource\requirements.txt" />
<Content Include="command_modules\azure-cli-role\azure\cli\command_modules\role\tests\recordings\expected_results.res" />
<Content Include="command_modules\azure-cli-role\azure\cli\command_modules\role\tests\recordings\test_role_assignment_scenario.yaml" />
<Content Include="command_modules\azure-cli-role\azure\cli\command_modules\role\tests\recordings\test_role_scenario.yaml" />
<Content Include="command_modules\azure-cli-role\README.rst" />
<Content Include="command_modules\azure-cli-role\requirements.txt" />
<Content Include="command_modules\azure-cli-storage\requirements.txt" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ def get_subscription_id_list(prefix, **kwargs):#pylint: disable=unused-argument
help='Organization id or service principal'
)

sp_name_type = CliArgumentType(
options_list=('--name', '-n')
)

register_cli_argument('login', 'password', password_type)
register_cli_argument('login', 'service_principal', service_principal_type)
register_cli_argument('login', 'username', username_type)
Expand All @@ -55,6 +51,3 @@ def get_subscription_id_list(prefix, **kwargs):#pylint: disable=unused-argument
help='account user, if missing, logout the current active account')

register_cli_argument('account', 'subscription_name_or_id', subscription_name_or_id_type)

register_cli_argument('account create-sp', 'name', sp_name_type)
register_cli_argument('account reset-sp-credentials', 'name', sp_name_type)
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,9 @@
#---------------------------------------------------------------------------------------------

# pylint: disable=too-few-public-methods,too-many-arguments,no-self-use
#TODO: update adal-python to support it
#from azure.cli._debug import should_disable_connection_verify
import datetime
import uuid
from dateutil.relativedelta import relativedelta

from adal.adal_error import AdalError

from azure.graphrbac.models import (ApplicationCreateParameters,
ApplicationUpdateParameters,
PasswordCredential)
from azure.graphrbac import GraphRbacManagementClient

from azure.cli._profile import Profile
from azure.cli._util import CLIError
import azure.cli._logging as _logging
Expand Down Expand Up @@ -81,85 +71,3 @@ def list_location():
from azure.cli.commands.parameters import get_subscription_locations
return get_subscription_locations()

def create_service_principal(name=None, secret=None, years=1):
'''create a service principal you can use with login command

:param str name: an unique uri. If missing, the command will generate one.
:param str secret: the secret used to login. If missing, command will generate one.
:param str years: Years the secret will be valid.
'''
start_date = datetime.datetime.now()
app_display_name = 'azure-cli-' + start_date.strftime('%Y-%m-%d-%H-%M-%S')
if name is None:
name = 'http://' + app_display_name

key_id = str(uuid.uuid4())
end_date = start_date + relativedelta(years=years)
secret = secret or str(uuid.uuid4())
app_cred = PasswordCredential(start_date, end_date, key_id, secret)
app_create_param = ApplicationCreateParameters(False, app_display_name,
'http://'+app_display_name, [name],
password_credentials=[app_cred])

profile = Profile()
cred, _, tenant = profile.get_login_credentials(for_graph_client=True)

client = GraphRbacManagementClient(cred, tenant)

#pylint: disable=no-member
aad_application = client.applications.create(app_create_param)
aad_sp = client.service_principals.create(aad_application.app_id, True)

_build_output_content(name, aad_sp.object_id, secret, tenant)

def reset_service_principal_credential(name, secret=None, years=1):
'''reset credential, on expiration or you forget it.

:param str name: the uri representing the name of the service principal
:param str secret: the secret used to login. If missing, command will generate one.
:param str years: Years the secret will be valid.
'''
profile = Profile()
cred, _, tenant = profile.get_login_credentials(for_graph_client=True)
client = GraphRbacManagementClient(cred, tenant)

#pylint: disable=no-member

#look for the existing application
query_exp = 'identifierUris/any(x:x eq \'{}\')'.format(name)
aad_apps = list(client.applications.list(filter=query_exp))
if not aad_apps:
raise CLIError('can\'t find a graph application matching \'{}\''.format(name))
#no need to check 2+ matches, as app id uri is unique
app = aad_apps[0]

#look for the existing service principal
query_exp = 'servicePrincipalNames/any(x:x eq \'{}\')'.format(name)
aad_sps = list(client.service_principals.list(filter=query_exp))
if not aad_sps:
raise CLIError('can\'t find an service principal matching \'{}\''.format(name))
sp_object_id = aad_sps[0].object_id

#build a new password credential and patch it
secret = secret or str(uuid.uuid4())
start_date = datetime.datetime.now()
end_date = start_date + relativedelta(years=years)
key_id = str(uuid.uuid4())
app_cred = PasswordCredential(start_date, end_date, key_id, secret)
app_create_param = ApplicationUpdateParameters(password_credentials=[app_cred])

client.applications.patch(app.object_id, app_create_param)

_build_output_content(name, sp_object_id, secret, tenant)

def _build_output_content(sp_name, sp_object_id, secret, tenant):
logger.warning("Service principal has been configured with name: '%s', secret: '%s'",
sp_name, secret)
logger.warning('Useful commands to manage azure:')
logger.warning(' Assign a role: "az role assignment create --assignee %s --role Contributor"',
sp_object_id)
logger.warning(' Log in: "az login --service-principal -u %s -p %s --tenant %s"',
sp_name, secret, tenant)
logger.warning(' Reset credentials: "az account reset-sp-credentials --name %s"',
sp_name)

Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
list_location,
list_subscriptions,
set_active_subscription,
account_clear,
create_service_principal,
reset_service_principal_credential)
account_clear)

cli_command('login', login)
cli_command('logout', logout)
Expand All @@ -24,6 +22,3 @@
cli_command('account clear', account_clear)
cli_command('account list-location', list_location)

cli_command('account create-sp', create_service_principal)
cli_command('account reset-sp-credentials', reset_service_principal_credential)

Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,32 @@
#---------------------------------------------------------------------------------------------
#pylint: disable=line-too-long
import azure.cli.commands.parameters #pylint: disable=unused-import

from azure.cli.commands import CliArgumentType
from azure.cli.commands import register_cli_argument

register_cli_argument('ad app', 'application_object_id', options_list=('--object-id',))
register_cli_argument('ad app', 'app_id', help='application id')
register_cli_argument('ad app', 'display_name', help=' the display name of the application')
register_cli_argument('ad app', 'homepage', help='the url where users can sign in and use your app.')
register_cli_argument('ad app', 'identifier', options_list=('--id',), help='identifier uri, application id, or object id')
register_cli_argument('ad app', 'identifier_uris', nargs='+', help='space separated unique URIs that Azure AD can use for this app.')
register_cli_argument('ad app', '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.')
register_cli_argument('ad app', 'start_date', help='the start date after which password or key would be valid. Default value is current time')
register_cli_argument('ad app', 'end_date', help='the end date till which password or key is valid. Default value is one year after current time')
register_cli_argument('ad app', 'key_value', help='the value for the key credentials associated with the application')
register_cli_argument('ad app', 'key_type', choices=['AsymmetricX509Cert', 'Password', 'Symmetric'], default='AsymmetricX509Cert',
Copy link
Contributor

@BurtBiel BurtBiel Aug 9, 2016

Choose a reason for hiding this comment

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

choices=['AsymmetricX509Cert', 'Password', 'Symmetric'], default='AsymmetricX509Cert', [](start = 44, length = 86)

can these be pulled from the SDK? Some of the VM params do this #Resolved

Copy link
Contributor Author

@yugangw-msft yugangw-msft Aug 9, 2016

Choose a reason for hiding this comment

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

I thought about doing you suggested, but as i checked out, the value is not modeled in SDK.
#Resolved

help='the type of the key credentials associated with the application')
register_cli_argument('ad app', 'key_usage', choices=['Sign', 'Verify'], default='Verify',
help='the usage of the key credentials associated with the application.')

sp_name_type = CliArgumentType(
options_list=('--name', '-n')
)
register_cli_argument('ad sp', 'identifier', options_list=('--id',), help='service principal name, or object id')
register_cli_argument('ad sp create', 'identifier', options_list=('--id',), help='identifier uri, application id, or object id of the associated application')
register_cli_argument('ad sp create-for-rbac', 'name', sp_name_type)
register_cli_argument('ad sp reset-credentials', 'name', sp_name_type)

register_cli_argument('ad', 'display_name', help='object\'s display name or its prefix')
register_cli_argument('ad', 'identifier_uri',
help='graph application identifier, must be in uri format')
Expand All @@ -18,6 +39,7 @@
register_cli_argument('ad user', 'mail_nickname',
help='mail alias. Defaults to user principal name')
register_cli_argument('ad user', 'force_change_password_next_login', action='store_true')

register_cli_argument('role assignment', 'role_assignment_name',
options_list=('--role-assignment-name', '-n'))
register_cli_argument('role assignment', 'role', help='role name or id')
Expand Down
Loading