Ejemplo n.º 1
0
    def setup_continuous_delivery(self, resource_group_name, name, repo_url,
                                  branch, git_token, slot, cd_app_type_details,
                                  cd_project_url, cd_create_account, location,
                                  test, private_repo_username,
                                  private_repo_password, webapp_list):
        """
        This method sets up CD for an Azure Web App thru Team Services
        """

        # Gather information about the Azure connection
        profile = Profile()
        subscription = profile.get_subscription()
        user = profile.get_current_account_user()
        cred, _, _ = profile.get_login_credentials(subscription_id=None)

        cd_manager = ContinuousDeliveryManager(self._update_progress)

        # Generate an Azure token with the VSTS resource app id
        auth_token = profile.get_access_token_for_resource(
            user, None, cd_manager.get_vsts_app_id())

        cd_manager.set_repository_info(repo_url, branch, git_token,
                                       private_repo_username,
                                       private_repo_password)
        cd_manager.set_azure_web_info(resource_group_name, name, cred,
                                      subscription['id'], subscription['name'],
                                      subscription['tenantId'], location)
        vsts_cd_status = cd_manager.setup_continuous_delivery(
            slot, cd_app_type_details, cd_project_url, cd_create_account,
            auth_token, test, webapp_list)
        return vsts_cd_status
Ejemplo n.º 2
0
    def setup_continuous_delivery(self, cli_ctx,
                                  resource_group_name, name, repo_url, branch, git_token,
                                  slot, cd_app_type_details, cd_project_url, cd_create_account, location,
                                  test, private_repo_username, private_repo_password, webapp_list):
        """
        This method sets up CD for an Azure Web App thru Team Services
        """

        # Gather information about the Azure connection
        profile = Profile(cli_ctx=cli_ctx)
        subscription = profile.get_subscription()
        user = profile.get_current_account_user()
        cred, _, _ = profile.get_login_credentials(subscription_id=None)

        cd_manager = ContinuousDeliveryManager(self._update_progress)

        # Generate an Azure token with the VSTS resource app id
        auth_token = profile.get_access_token_for_resource(user, None, cd_manager.get_vsts_app_id())

        cd_manager.set_repository_info(repo_url, branch, git_token, private_repo_username, private_repo_password)
        cd_manager.set_azure_web_info(resource_group_name, name, cred, subscription['id'],
                                      subscription['name'], subscription['tenantId'], location)
        vsts_cd_status = cd_manager.setup_continuous_delivery(slot, cd_app_type_details, cd_project_url,
                                                              cd_create_account, auth_token, test, webapp_list)
        return vsts_cd_status
Ejemplo n.º 3
0
def logout(username=None):
    """Log out to remove access to Azure subscriptions"""
    if in_cloud_console():
        raise CLIError(_CLOUD_CONSOLE_ERR_TEMPLATE.format('logout'))

    profile = Profile()
    if not username:
        username = profile.get_current_account_user()
    profile.logout(username)
Ejemplo n.º 4
0
def logout(username=None):
    """Log out to remove access to Azure subscriptions"""
    if _in_cloud_console():
        raise CLIError(_CLOUD_CONSOLE_ERR_TEMPLATE.format('logout'))

    profile = Profile()
    if not username:
        username = profile.get_current_account_user()
    profile.logout(username)
Ejemplo n.º 5
0
def logout(cmd, username=None):
    """Log out to remove access to Azure subscriptions"""
    if in_cloud_console():
        logger.warning(_CLOUD_CONSOLE_LOGOUT_WARNING)

    profile = Profile(cli_ctx=cmd.cli_ctx)
    if not username:
        username = profile.get_current_account_user()
    profile.logout(username)
Ejemplo n.º 6
0
def logout(cmd, username=None):
    """Log out to remove access to Azure subscriptions"""
    if in_cloud_console():
        logger.warning(_CLOUD_CONSOLE_LOGOUT_WARNING)

    profile = Profile(cli_ctx=cmd.cli_ctx)
    if not username:
        username = profile.get_current_account_user()
    profile.logout(username)
Ejemplo n.º 7
0
def logout(username=None):
    """Log out to remove access to Azure subscriptions"""
    if in_cloud_console():
        logger.warning(_CLOUD_CONSOLE_WARNING_TEMPLATE, 'logout')
        return

    profile = Profile()
    if not username:
        username = profile.get_current_account_user()
    profile.logout(username)
Ejemplo n.º 8
0
def logout(username=None):
    """Log out to remove access to Azure subscriptions"""
    if in_cloud_console():
        logger.warning(_CLOUD_CONSOLE_WARNING_TEMPLATE, 'logout')
        return

    profile = Profile()
    if not username:
        username = profile.get_current_account_user()
    profile.logout(username)
Ejemplo n.º 9
0
def get_default_subscription_info():
    """
    Returns the Id, name, tenantID and environmentName of the default subscription
    None if no default is set or no subscription is found
    """
    profile = Profile()
    dummy_user = profile.get_current_account_user()     # noqa: F841
    subscriptions = profile.load_cached_subscriptions(False)
    for subscription in subscriptions:
        if subscription['isDefault']:
            return subscription['id'], subscription['name'], subscription['tenantId'], subscription['environmentName']
    logger.debug('Your account does not have a default Azure subscription. Please run \'az login\' to setup account.')
    return None, None, None, None
Ejemplo n.º 10
0
    def test_get_current_account_user(self, mock_read_cred_file):
        #setup
        mock_read_cred_file.return_value = [Test_Profile.token_entry1]

        storage_mock = {'subscriptions': None}
        profile = Profile(storage_mock)
        consolidated = Profile._normalize_properties(self.user1,
                                                     [self.subscription1],
                                                     False)
        profile._set_subscriptions(consolidated)
        #action
        user = profile.get_current_account_user()

        #verify
        self.assertEqual(user, self.user1)
Ejemplo n.º 11
0
    def test_get_current_account_user(self, mock_read_cred_file):
        #setup
        mock_read_cred_file.return_value = [Test_Profile.token_entry1]

        storage_mock = {'subscriptions': None}
        profile = Profile(storage_mock)
        consolidated = Profile._normalize_properties(self.user1,
                                                     [self.subscription1],
                                                     False)
        profile._set_subscriptions(consolidated)
        #action
        user = profile.get_current_account_user()

        #verify
        self.assertEqual(user, self.user1)
Ejemplo n.º 12
0
def get_token_from_az_logins(organization, pat_token_present):
    profile = Profile()
    dummy_user = profile.get_current_account_user()  # noqa: F841
    subscriptions = profile.load_cached_subscriptions(False)
    tenantsDict = OrderedDict()

    # first loop to make sure the first identity we try with is coming from selected subscription
    for subscription in subscriptions:
        if subscription['isDefault'] == "true":
            tenantsDict[(subscription['tenantId'],
                         subscription['user']['name'])] = ''

    for subscription in subscriptions:
        tenantsDict[(subscription['tenantId'],
                     subscription['user']['name'])] = ''

    skipValidateToken = False
    if pat_token_present is False and len(tenantsDict) == 1:
        skipValidateToken = True

    try:
        for key, dummy_value in tenantsDict.items():
            try:
                logger.debug(
                    'trying to get token (temp) for tenant %s and user %s ',
                    key[0], key[1])
                token = get_token_from_az_login(profile, key[1], key[0])
                credentials = BasicAuthentication('', token)

                if skipValidateToken is True:
                    return token
                if validate_token_for_instance(organization, credentials):
                    return token
                logger.debug('invalid token obtained for tenant %s', key[0])
            except BaseException as ex2:
                logger.debug(ex2)
                logger.debug('failed while trying to get token for tenant %s',
                             key[0])
    except BaseException as ex:
        logger.debug(ex)

    return ''
Ejemplo n.º 13
0
def _get_login_account_principal_id(cli_ctx):
    from azure.cli.core._profile import Profile
    from azure.graphrbac import GraphRbacManagementClient
    profile = Profile(cli_ctx=cli_ctx)
    cred, _, tenant_id = profile.get_login_credentials(
        resource=cli_ctx.cloud.endpoints.active_directory_graph_resource_id)
    client = GraphRbacManagementClient(
        cred,
        tenant_id,
        base_url=cli_ctx.cloud.endpoints.active_directory_graph_resource_id)
    assignee = profile.get_current_account_user()
    result = list(
        client.users.list(filter=f"userPrincipalName eq '{assignee}'"))
    if not result:
        result = list(
            client.service_principals.list(
                filter=f"servicePrincipalNames/any(c:c eq '{assignee}')"))
    if not result:
        raise CLIInternalError((
            f"Failed to retrieve principal id for '{assignee}', which is needed to create a "
            f"role assignment"))
    return result[0].object_id
Ejemplo n.º 14
0
def teamcloud_deploy(
        cmd,
        client,
        name,
        location,
        resource_group_name='TeamCloud',  # pylint: disable=too-many-statements, too-many-locals
        principal_name=None,
        principal_password=None,
        tags=None,
        version=None,
        skip_app_deployment=False,
        skip_name_validation=False,
        skip_admin_user=False,
        prerelease=False,
        index_url=None):
    from azure.cli.core._profile import Profile
    from .vendored_sdks.teamcloud.models import UserDefinition
    from ._deploy_utils import (get_github_latest_release, get_index_teamcloud,
                                deploy_arm_template_at_resource_group,
                                get_resource_group_by_name,
                                create_resource_group_name,
                                create_resource_manager_sp, set_appconfig_keys,
                                zip_deploy_app)

    cli_ctx = cmd.cli_ctx
    location = location.lower()

    hook = cli_ctx.get_progress_controller()
    hook.begin()

    if version or prerelease:
        if index_url:
            raise CLIError(
                '--index-url can not be used with --version or --pre.')

    if index_url is None:
        version = version or get_github_latest_release(
            cmd.cli_ctx, 'TeamCloud', prerelease=prerelease)
        index_url = 'https://github.com/microsoft/TeamCloud/releases/download/{}/index.json'.format(
            version)

    hook.add(message='Fetching index.json from GitHub')

    index_teamcloud = get_index_teamcloud(index_url=index_url)

    deploy_url, api_zip_url, orchestrator_zip_url = index_teamcloud.get(
        'deployUrl'), index_teamcloud.get('apiZipUrl'), index_teamcloud.get(
            'orchestratorZipUrl')

    if not deploy_url:
        raise CLIError('No deploy url found found in index')
    if not api_zip_url:
        raise CLIError('No zip url for the api found found in index')
    if not orchestrator_zip_url:
        raise CLIError('No zip url for the orchestrator found found in index')

    hook.add(message='Getting resource group {}'.format(resource_group_name))

    rg, _ = get_resource_group_by_name(cli_ctx, resource_group_name)
    if rg is None:
        hook.add(message="Resource group '{}' not found".format(
            resource_group_name))
        hook.add(
            message="Creating resource group '{}'".format(resource_group_name))
        rg, _ = create_resource_group_name(cli_ctx, resource_group_name,
                                           location)

    profile = Profile(cli_ctx=cli_ctx)

    if principal_name is None and principal_password is None:
        hook.add(message='Creating AAD app registration')
        resource_manager_sp = create_resource_manager_sp(cmd)
    else:
        _, _, tenant_id = profile.get_login_credentials(
            resource=cli_ctx.cloud.endpoints.active_directory_graph_resource_id
        )
        resource_manager_sp = {
            'appId': principal_name,
            'password': principal_password,
            'tenant': tenant_id
        }

    parameters = []
    parameters.append('webAppName={}'.format(name))
    parameters.append('resourceManagerIdentityClientId={}'.format(
        resource_manager_sp['appId']))
    parameters.append('resourceManagerIdentityClientSecret={}'.format(
        resource_manager_sp['password']))

    hook.add(message='Deploying ARM template')
    outputs = deploy_arm_template_at_resource_group(cmd,
                                                    resource_group_name,
                                                    template_uri=deploy_url,
                                                    parameters=[parameters])

    api_url = outputs['apiUrl']['value']
    orchestrator_url = outputs['orchestratorUrl']['value']
    api_app_name = outputs['apiAppName']['value']
    orchestrator_app_name = outputs['orchestratorAppName']['value']
    config_service_conn_string = outputs['configServiceConnectionString'][
        'value']
    config_service_imports = outputs['configServiceImport']['value']

    if not api_url:
        raise CLIError(
            'ARM template outputs did not include a value for apiUrl')
    if not orchestrator_url:
        raise CLIError(
            'ARM template outputs did not include a value for orchestratorUrl')
    if not api_app_name:
        raise CLIError(
            'ARM template outputs did not include a value for apiAppName')
    if not orchestrator_app_name:
        raise CLIError(
            'ARM template outputs did not include a value for orchestratorAppName'
        )
    if not config_service_conn_string:
        raise CLIError(
            'ARM template outputs did not include a value for configServiceConnectionString'
        )
    if not config_service_imports:
        raise CLIError(
            'ARM template outputs did not include a value for configServiceImport'
        )

    config_kvs = []
    for k, v in config_service_imports.items():
        config_kvs.append({'key': k, 'value': v})

    hook.add(
        message='Adding ARM template outputs to App Configuration service')
    set_appconfig_keys(cli_ctx, config_service_conn_string, config_kvs)

    if skip_app_deployment:
        logger.warning(
            'IMPORTANT: --skip-deploy prevented source code for the TeamCloud instance deployment. '
            'To deploy the applications use `az tc upgrade`.')
    else:
        hook.add(message='Deploying Orchestrator source code')
        zip_deploy_app(cli_ctx, resource_group_name, orchestrator_app_name,
                       orchestrator_zip_url)

        hook.add(message='Deploying API source code')
        zip_deploy_app(cli_ctx, resource_group_name, api_app_name, api_zip_url)

        version_string = version or 'the latest version'
        hook.add(message='Successfully created TeamCloud instance ({})'.format(
            version_string))

    if skip_admin_user:
        logger.warning(
            'IMPORTANT: --redeploy prevented adding you as an Admin user to the TeamCloud instance deployment.'
        )
    else:
        me = profile.get_current_account_user()
        hook.add(message="Adding '{}' as an admin user".format(me))

        client._client.config.base_url = api_url
        user_definition = UserDefinition(identifier=me,
                                         role='Admin',
                                         properties=None)
        _ = client.create_team_cloud_admin_user(user_definition)

    hook.end(message=' ')
    logger.warning(' ')
    logger.warning('TeamCloud instance successfully created at: %s', api_url)
    logger.warning(
        'Use `az configure --defaults tc-base-url=%s` to configure '
        'this as your default TeamCloud instance', api_url)

    result = {
        'deployed': not skip_app_deployment,
        'version': version or 'latest',
        'name': name,
        'base_url': api_url,
        'location': location,
        'api': {
            'name': api_app_name,
            'url': api_url
        },
        'orchestrator': {
            'name': orchestrator_app_name,
            'url': orchestrator_url
        },
        'service_principal': {
            'appId': resource_manager_sp['appId'],
            # 'password': resource_manager_sp['password'],
            'tenant': resource_manager_sp['tenant']
        }
    }

    return result
Ejemplo n.º 15
0
def logout(username=None):
    """Log out to remove access to Azure subscriptions"""
    profile = Profile()
    if not username:
        username = profile.get_current_account_user()
    profile.logout(username)
Ejemplo n.º 16
0
def teamcloud_deploy(
        cmd,
        client,
        name,
        location=None,
        resource_group_name='TeamCloud',  # pylint: disable=too-many-statements, too-many-locals
        principal_name=None,
        principal_password=None,
        tags=None,
        version=None,
        skip_app_deployment=False,
        skip_name_validation=False,
        skip_admin_user=False,
        prerelease=False,
        index_url=None):
    from re import sub
    from azure.cli.core._profile import Profile
    from .vendored_sdks.teamcloud.models import UserDefinition, TeamCloudInstance, AzureResourceGroup
    from ._deploy_utils import (get_index_teamcloud,
                                deploy_arm_template_at_resource_group,
                                get_resource_group_by_name,
                                create_resource_group_name,
                                create_resource_manager_sp, set_appconfig_keys,
                                zip_deploy_app, get_arm_output)

    cli_ctx = cmd.cli_ctx

    hook = cli_ctx.get_progress_controller()
    hook.begin()

    hook.add(message='Fetching index.json from GitHub')
    version, deploy_url, api_zip_url, orchestrator_zip_url = get_index_teamcloud(
        cli_ctx, version, prerelease, index_url)

    hook.add(message='Getting resource group {}'.format(resource_group_name))
    rg, sub_id = get_resource_group_by_name(cli_ctx, resource_group_name)
    if rg is None:
        if location is None:
            raise CLIError(
                "--location/-l is required if resource group '{}' does not exist"
                .format(resource_group_name))
        hook.add(message="Resource group '{}' not found".format(
            resource_group_name))
        hook.add(
            message="Creating resource group '{}'".format(resource_group_name))
        rg, sub_id = create_resource_group_name(cli_ctx, resource_group_name,
                                                location)

    profile = Profile(cli_ctx=cli_ctx)

    if principal_name is None and principal_password is None:
        hook.add(message='Creating AAD app registration')
        resource_manager_sp = create_resource_manager_sp(cmd, name)
    else:
        _, _, tenant_id = profile.get_login_credentials(
            resource=cli_ctx.cloud.endpoints.active_directory_graph_resource_id
        )
        resource_manager_sp = {
            'appId': principal_name,
            'password': principal_password,
            'tenant': tenant_id
        }

    parameters = []
    parameters.append('webAppName={}'.format(name))
    parameters.append('resourceManagerIdentityClientId={}'.format(
        resource_manager_sp['appId']))
    parameters.append('resourceManagerIdentityClientSecret={}'.format(
        resource_manager_sp['password']))

    hook.add(message='Deploying ARM template')
    outputs = deploy_arm_template_at_resource_group(cmd,
                                                    resource_group_name,
                                                    template_uri=deploy_url,
                                                    parameters=[parameters])

    api_url = get_arm_output(outputs, 'apiUrl')
    orchestrator_url = get_arm_output(outputs, 'orchestratorUrl')
    api_app_name = get_arm_output(outputs, 'apiAppName')
    orchestrator_app_name = get_arm_output(outputs, 'orchestratorAppName')
    config_service_conn_string = get_arm_output(
        outputs, 'configServiceConnectionString')
    config_service_imports = get_arm_output(outputs, 'configServiceImport')

    config_kvs = []
    for k, v in config_service_imports.items():
        config_kvs.append({'key': k, 'value': v})

    hook.add(
        message='Adding ARM template outputs to App Configuration service')
    set_appconfig_keys(cmd, config_service_conn_string, config_kvs)

    if skip_app_deployment:
        logger.warning(
            'IMPORTANT: --skip-app-deployment prevented source code for the TeamCloud instance deployment. '
            'To deploy the applications use `az tc upgrade`.')
    else:
        hook.add(message='Deploying Orchestrator source code')
        zip_deploy_app(cli_ctx, resource_group_name, orchestrator_app_name,
                       orchestrator_zip_url)

        hook.add(message='Deploying API source code')
        zip_deploy_app(cli_ctx, resource_group_name, api_app_name, api_zip_url)

        version_string = version or 'the latest version'
        hook.add(message='Successfully created TeamCloud instance ({})'.format(
            version_string))

    _ensure_base_url(client, api_url)

    if skip_admin_user:
        logger.warning(
            'IMPORTANT: --skip-admin-user prevented adding you as an Admin user to the TeamCloud instance deployment.'
        )
    else:
        me = profile.get_current_account_user()
        me = sub('http[s]?://', '', me)
        hook.add(message="Adding '{}' as an admin user".format(me))

        user_definition = UserDefinition(identifier=me,
                                         role='Admin',
                                         properties=None)
        _ = client.create_team_cloud_admin_user(user_definition)

    hook.add(message='Adding TeamCloud instance information')
    resource_group = AzureResourceGroup(id=rg.id,
                                        name=rg.name,
                                        region=rg.location,
                                        subscription_id=sub_id)
    teamcloud_instance = TeamCloudInstance(version=version,
                                           resource_group=resource_group,
                                           tags=tags)
    _ = client.create_team_cloud_instance(teamcloud_instance)

    hook.end(message=' ')
    logger.warning(' ')
    logger.warning('TeamCloud instance successfully created at: %s', api_url)
    logger.warning(
        'Use `az configure --defaults tc-base-url=%s` to configure '
        'this as your default TeamCloud instance', api_url)

    result = {
        'deployed': not skip_app_deployment,
        'version': version or 'latest',
        'name': name,
        'base_url': api_url,
        'location': rg.location,
        'api': {
            'name': api_app_name,
            'url': api_url
        },
        'orchestrator': {
            'name': orchestrator_app_name,
            'url': orchestrator_url
        },
        'service_principal': {
            'appId': resource_manager_sp['appId'],
            # 'password': resource_manager_sp['password'],
            'tenant': resource_manager_sp['tenant']
        }
    }

    return result
Ejemplo n.º 17
0
def logout(username=None):
    """Log out to remove access to Azure subscriptions"""
    profile = Profile()
    if not username:
        username = profile.get_current_account_user()
    profile.logout(username)
Ejemplo n.º 18
0
def _get_user_azure_id():
    try:
        profile = Profile()
        return _get_hash(profile.get_current_account_user())
    except CLIError: #pylint: disable=broad-except
        pass