Esempio n. 1
0
def get_kubernetes_namespace(organization, project, cluster, subscription_id,
                             subscription_name, tenant_id, azure_env):
    choice_list = []
    existing_namespace_list = []
    choice_list.append("Create new")
    se_request_obj = get_se_kubernetes_namespace_request_obj(
        subscription_id, subscription_name, cluster['id'], cluster['name'],
        cluster['fqdn'], azure_env, tenant_id)
    se_client = get_service_endpoint_client(organization=organization)
    se_result = se_client.execute_service_endpoint_request(
        service_endpoint_request=se_request_obj,
        project=project,
        endpoint_id=cluster['name'])
    if se_result.result:
        import json
        for namespace in se_result.result:
            ns_json_obj = json.loads(namespace)
            existing_namespace_list.append(ns_json_obj['Value'])
            choice_list.append(ns_json_obj['Value'])
    choice = prompt_user_friendly_choice_list(
        "Which kubernetes namespace do you want to target?", choice_list)
    if choice == 0:
        create_namespace = True
        namespace = prompt_not_empty(
            "Enter a name for new namespace to create: ")
        print('')
    else:
        create_namespace = False
        namespace = existing_namespace_list[choice - 1]
    return create_namespace, namespace
Esempio n. 2
0
def create_github_branch(repo, source):
    """
    API Documentation - https://developer.github.com/v3/git/refs/#create-a-reference
    """
    token = get_github_pat_token()
    # Validate new branch name is valid
    branch_is_valid = False
    while not branch_is_valid:
        new_branch = prompt_not_empty(msg='Enter new branch name to create: ')
        ref, is_folder = get_github_branch(repo, new_branch)
        if not ref and not is_folder:
            branch_is_valid = True
        else:
            logger.warning('Not a valid branch name.')
    # Get source branch ref
    ref_item, is_folder = get_github_branch(repo, source)
    if not ref_item or is_folder:
        raise CLIError('Branch ({branch}) does not exist.'.format(branch=source))
    source_ref = ref_item['object']['sha']
    create_github_ref_url = 'https://api.github.com/repos/{repo_id}/git/refs'.format(repo_id=repo)
    create_github_ref_request_body = {
        "ref": resolve_git_ref_heads(new_branch),
        "sha": source_ref
    }
    create_response = requests.post(url=create_github_ref_url, auth=('', token),
                                    json=create_github_ref_request_body, headers=get_application_json_header())
    if not create_response.status_code == _HTTP_CREATED_STATUS:
        raise CLIError('Branch creation failed. Error: ({err})'.format(err=create_response.reason))
    return get_branch_name_from_ref(new_branch)
Esempio n. 3
0
def get_github_service_endpoint(organization, project):
    """
    This will try to create a GitHub service connection if there is no existing one in the project
    GitHub pat token will be asked for interactively or can be provided
    by setting the Environment variable AZ_DEVOPS_GITHUB_PAT_ENVKEY.
    Service endpoint connection name is asked as input from the user
    """
    from azext_devops.dev.common.identities import get_current_identity, get_account_from_identity
    authenticated_user_unique_id = get_account_from_identity(
        get_current_identity(organization))
    se_client = get_service_endpoint_client(organization)
    existing_service_endpoints = _get_service_endpoints(
        organization, project, 'github')
    service_endpoints_choice_list = ['Create new GitHub service connection']
    github_service_endpoints = []
    choice = 0
    for endpoint in existing_service_endpoints:
        if (endpoint.authorization.scheme == 'InstallationToken'
                or authenticated_user_unique_id
                == endpoint.created_by.unique_name):
            service_endpoints_choice_list.append('{}'.format(endpoint.name))
            github_service_endpoints.append(endpoint)
    if github_service_endpoints:
        choice = prompt_user_friendly_choice_list(
            "Which service connection do you want to use to communicate with GitHub?",
            service_endpoints_choice_list)
        if choice > 0:
            logger.debug('Using service endpoint index (%s) name (%s)', choice,
                         github_service_endpoints[choice - 1].name)
            return github_service_endpoints[choice - 1].id
    logger.debug("Creating a new service endpoint.")
    github_pat = get_github_pat_token()
    se_name = prompt_not_empty('Enter a service connection name to create? ')
    print('')
    service_endpoint_authorization = EndpointAuthorization(
        parameters={'accessToken': github_pat}, scheme='PersonalAccessToken')
    service_endpoint_to_create = ServiceEndpoint(
        authorization=service_endpoint_authorization,
        name=se_name,
        type='github',
        url='https://github.com/')
    return se_client.create_service_endpoint(service_endpoint_to_create,
                                             project).id
def get_new_azure_repo_branch(organization, project, repository, source):
    from azext_devops.dev.repos.ref import list_refs, create_ref
    # get source ref object id
    object_id = None
    branch = resolve_git_ref_heads(source)
    filter_str = branch[5:]  # remove 'refs' to use as filter
    refs_list = list_refs(filter=filter_str, repository=repository, organization=organization, project=project)
    for ref in refs_list:
        if ref.name == branch:
            object_id = ref.object_id
            break
    if not object_id:
        raise CLIError('Cannot fetch source branch details for branch {br}'.format(br=branch))
    # get valid branch name
    branch_is_valid = False
    while not branch_is_valid:
        new_branch = prompt_not_empty(msg='Enter new branch name to create: ')
        try:
            create_ref('heads/' + new_branch, object_id, repository, organization, project)
            branch_is_valid = True
        except Exception:  # pylint: disable=broad-except
            logger.warning('Not a valid branch name.')
    return new_branch
def _create_and_get_yml_path(
        cix_client,
        repository_type,
        repo_id,
        repo_name,
        branch,  # pylint: disable=too-many-locals, too-many-statements
        service_endpoint,
        project,
        organization):
    logger.debug(
        'No yaml file was given. Trying to find the yaml file in the repo.')
    queue_branch = branch
    default_yml_exists = False
    yml_names = []
    yml_options = []
    configurations = cix_client.get_configurations(
        project=project,
        repository_type=repository_type,
        repository_id=repo_id,
        branch=branch,
        service_connection_id=service_endpoint)
    for configuration in configurations:
        if configuration.path.strip('/') == 'azure-pipelines.yml':
            default_yml_exists = True
        logger.debug('The repo has a yaml pipeline definition. Path: %s',
                     configuration.path)
        custom_name = 'Existing yaml (path={})'.format(configuration.path)
        yml_names.append(custom_name)
        yml_options.append(
            YmlOptions(name=custom_name,
                       content=configuration.content,
                       id='customid',
                       path=configuration.path))

    recommendations = cix_client.get_template_recommendations(
        project=project,
        repository_type=repository_type,
        repository_id=repo_id,
        branch=branch,
        service_connection_id=service_endpoint)
    logger.debug('List of recommended templates..')
    # sort recommendations
    from operator import attrgetter
    recommendations = sorted(recommendations,
                             key=attrgetter('recommended_weight'),
                             reverse=True)
    for recommendation in recommendations:
        yml_names.append(recommendation.name)
        yml_options.append(
            YmlOptions(name=recommendation.name,
                       content=recommendation.content,
                       id=recommendation.id,
                       description=recommendation.description,
                       params=recommendation.parameters,
                       assets=recommendation.assets))
    temp_filename = None
    files = []
    yml_selection_index = 0
    proceed_selection = 1
    while proceed_selection == 1:
        proceed_selection = 0
        # Clear files since user can change the template now
        del files[:]
        yml_selection_index = prompt_user_friendly_choice_list(
            "Which template do you want to use for this pipeline?", yml_names)
        if yml_options[yml_selection_index].params:
            yml_options[yml_selection_index].content, yml_options[
                yml_selection_index].assets = _handle_yml_props(
                    params_required=yml_options[yml_selection_index].params,
                    template_id=yml_options[yml_selection_index].id,
                    cix_client=cix_client,
                    repo_name=repo_name,
                    organization=organization,
                    project=project)
        temp_dir = tempfile.mkdtemp(prefix='AzurePipelines_')
        temp_filename = os.path.join(temp_dir, 'azure-pipelines.yml')
        f = open(temp_filename, mode='w')
        f.write(yml_options[yml_selection_index].content)
        f.close()
        assets = yml_options[yml_selection_index].assets
        if assets:
            for asset in assets:
                files.append(Files(asset.destination_path, asset.content))
        view_choice = prompt_user_friendly_choice_list(
            'Do you want to view/edit the template yaml before proceeding?',
            ['Continue with generated yaml', 'View or edit the yaml'])
        if view_choice == 1:
            open_file(temp_filename)
            proceed_selection = prompt_user_friendly_choice_list(
                'Do you want to proceed creating a pipeline?',
                ['Proceed with this yaml', 'Choose another template'])
    # Read updated data from the file
    f = open(temp_filename, mode='r')
    content = f.read()
    f.close()
    delete_dir(temp_dir)
    checkin_path = 'azure-pipelines.yml'
    if default_yml_exists and not yml_options[
            yml_selection_index].path:  # We need yml path from user
        logger.warning(
            'A yaml file azure-pipelines.yml already exists in the repository root.'
        )
        checkin_path = prompt_not_empty(
            msg=
            'Enter a yaml file path to checkin the new pipeline yaml in the repository? ',
            help_string=
            'e.g. /new_azure-pipeline.yml to add in the root folder.')
        print('')
    files.append(Files(checkin_path, content))
    print('Files to be added to your repository ({numfiles})'.format(
        numfiles=len(files)))
    count_file = 1
    for file in files:
        print('{index}) {file}'.format(index=count_file, file=file.path))
        count_file = count_file + 1
    print('')
    if default_yml_exists and checkin_path.strip('/') == 'azure-pipelines.yml':
        print('Edits on the existing yaml can be done in the code repository.')
    else:
        queue_branch = push_files_to_repository(organization, project,
                                                repo_name, branch, files,
                                                repository_type)
    return checkin_path, queue_branch