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
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)
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