Exemplo n.º 1
0
def delete_management_cluster(cmd, yes=False):  # pylint: disable=unused-argument
    exit_if_no_management_cluster()
    msg = 'Do you want to delete Cluster API components from the current cluster?'
    if not yes and not prompt_y_n(msg, default="n"):
        return

    command = ["clusterctl", "delete", "--all",
               "--include-crd", "--include-namespace"]
    try:
        output = subprocess.check_output(command, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault("Couldn't delete components from management cluster") from err
    namespaces = [
        "capi-kubeadm-bootstrap-system",
        "capi-kubeadm-control-plane-system",
        "capi-system",
        "capi-webhook-system",
        "capz-system",
        "cert-manager",
    ]
    command = ["kubectl", "delete", "namespace", "--ignore-not-found"] + namespaces
    try:
        output = subprocess.check_output(command, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault("Couldn't delete namespaces from management cluster") from err
Exemplo n.º 2
0
def delete_management_cluster(cmd):  # pylint: disable=unused-argument
    # TODO: add user confirmation
    command = [
        "clusterctl", "delete", "--all", "--include-crd", "--include-namespace"
    ]
    try:
        output = subprocess.check_output(command, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault(err)
    namespaces = [
        "capi-kubeadm-bootstrap-system",
        "capi-kubeadm-control-plane-system",
        "capi-system",
        "capi-webhook-system",
        "capz-system",
        "cert-manager",
    ]
    command = ["kubectl", "delete", "namespace", "--ignore-not-found"
               ] + namespaces
    try:
        output = subprocess.check_output(command, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault(err)
Exemplo n.º 3
0
def init_environment(cmd, prompt=True):
    check_prereqs(cmd, install=True)
    # Create a management cluster if needed
    try:
        find_management_cluster_retry(cmd)
    except ResourceNotFoundError as err:
        if str(err) == "No Cluster API installation found":
            _install_capz_components(cmd)
    except subprocess.CalledProcessError:
        if prompt:
            choices = ["kind - a local Docker container-based cluster",
                       "AKS - a managed cluster in the Azure cloud",
                       "exit - don't create a management cluster"]
            prompt = """
No Kubernetes cluster was found using the default configuration.

Cluster API needs a "management cluster" to run its components.
Learn more from the Cluster API Book:
https://cluster-api.sigs.k8s.io/user/concepts.html

Where do you want to create a management cluster?
"""
            choice_index = prompt_choice_list(prompt, choices)
        else:
            choice_index = 0
        cluster_name = "capi-manager"
        if choice_index == 0:
            check_kind(cmd, install=not prompt)
            begin_msg = 'Creating local management cluster "{}" with kind'.format(cluster_name)
            end_msg = '✓ Created local management cluster "{}"'.format(cluster_name)
            with Spinner(cmd, begin_msg, end_msg):
                command = ["kind", "create", "cluster", "--name", cluster_name]
                try:
                    # if --verbose, don't capture stderr
                    stderr = None if is_verbose() else subprocess.STDOUT
                    output = subprocess.check_output(command, universal_newlines=True, stderr=stderr)
                    logger.info("%s returned:\n%s", " ".join(command), output)
                except subprocess.CalledProcessError as err:
                    raise UnclassifiedUserFault("Couldn't create kind management cluster") from err
        elif choice_index == 1:
            with Spinner(cmd, "Creating Azure resource group", "✓ Created Azure resource group"):
                command = ["az", "group", "create", "-l", "southcentralus", "--name", cluster_name]
                try:
                    output = subprocess.check_output(command, universal_newlines=True)
                    logger.info("%s returned:\n%s", " ".join(command), output)
                except subprocess.CalledProcessError as err:
                    raise UnclassifiedUserFault("Couldn't create Azure resource group") from err
            with Spinner(cmd, "Creating Azure management cluster with AKS", "✓ Created AKS management cluster"):
                command = ["az", "aks", "create", "-g", cluster_name, "--name", cluster_name]
                try:
                    output = subprocess.check_output(command, universal_newlines=True)
                    logger.info("%s returned:\n%s", " ".join(command), output)
                except subprocess.CalledProcessError as err:
                    raise UnclassifiedUserFault("Couldn't create AKS management cluster") from err
        else:
            return
        _install_capz_components(cmd)
Exemplo n.º 4
0
def find_kubectl_resource_names(resource_type, error_msg, kubeconfig=None):
    command = ["kubectl", "get", resource_type, "--output", "name"]
    command += add_kubeconfig_to_command(kubeconfig)
    try:
        return run_shell_command(command).splitlines()
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault(error_msg) from err
Exemplo n.º 5
0
def show_management_cluster(_cmd, yes=False):
    # TODO: check to see if a management cluster is specified in the config
    config = get_default_cli().config
    # Config can also be set by the AZURE_CAPI_KUBECONFIG environment variable.
    kubeconfig = config.get("capi",
                            "kubeconfig",
                            fallback=os.environ.get("KUBECONFIG"))
    if not kubeconfig:
        raise InvalidArgumentValueError("no kubeconfig")
    # make a $HOME/.azure/capi directory for storing cluster configurations
    path = os.path.join(get_config_dir(), "capi")
    if not os.path.exists(path):
        os.makedirs(path)
    # TODO: if not
    command = [
        "kubectl", "config", "get-contexts", "--no-headers", "--output", "name"
    ]
    try:
        output = subprocess.check_output(command, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
        contexts = output.splitlines()
        logger.info(contexts)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault(err)

    msg = path + "ok"
    if not yes and prompt_y_n(msg, default="n"):
        logger.info("yes")
Exemplo n.º 6
0
def data_collection_rules_create(client,
                                 resource_group_name,
                                 data_collection_rule_name,
                                 rule_file,
                                 location=None,
                                 tags=None,
                                 description=None):
    from azure.cli.core.util import get_file_json
    from azure.cli.core.azclierror import FileOperationError, UnclassifiedUserFault
    body = {}
    body['location'] = location
    body['tags'] = tags
    body['description'] = description
    try:
        json_data = get_file_json(rule_file)
    except FileNotFoundError:
        raise FileOperationError("No such file: " + str(rule_file))
    except IsADirectoryError:
        raise FileOperationError("Is a directory: " + str(rule_file))
    except PermissionError:
        raise FileOperationError("Permission denied: " + str(rule_file))
    except OSError as e:
        raise UnclassifiedUserFault(e)
    for key_prop in json_data:
        if key_prop == 'properties':
            data = json_data['properties']
        else:
            data = json_data
    for key in data:
        if key == 'dataSources':
            body['data_sources'] = {}
            for key_ds in data['dataSources']:
                if key_ds == 'performanceCounters':
                    body['data_sources']['performance_counters'] = data[
                        'dataSources']['performanceCounters']
                if key_ds == 'windowsEventLogs':
                    body['data_sources']['windows_event_logs'] = data[
                        'dataSources']['windowsEventLogs']
                if key_ds == 'syslog':
                    body['data_sources']['syslog'] = data['dataSources'][
                        'syslog']
                if key_ds == 'extensions':
                    body['data_sources']['extensions'] = data['dataSources'][
                        'extensions']
        if key == 'destinations':
            body['destinations'] = {}
            for key_de in data['destinations']:
                if key_de == 'logAnalytics':
                    body['destinations']['log_analytics'] = data[
                        'destinations']['logAnalytics']
                if key_de == 'azureMonitorMetrics':
                    body['destinations']['azure_monitor_metrics'] = data[
                        'destinations']['azureMonitorMetrics']
        if key == 'dataFlows':
            body['data_flows'] = data['dataFlows']
    return _data_collection_rules_create(
        client,
        resource_group_name=resource_group_name,
        data_collection_rule_name=data_collection_rule_name,
        body=body)
Exemplo n.º 7
0
def init_environment(cmd,
                     prompt=True,
                     management_cluster_name=None,
                     resource_group_name=None,
                     location=None):
    check_prereqs(cmd, install=True)
    # Create a management cluster if needed
    use_new_cluster = False
    pre_prompt = None
    try:
        find_management_cluster_retry(cmd)
        cluster_name = find_cluster_in_current_context()
        if prompt and not prompt_y_n(
                f"Do you want to use {cluster_name} as the management cluster?"
        ):
            use_new_cluster = True
        else:
            return True
    except ResourceNotFoundError as err:
        error_msg = err.error_msg
        if management_cluster_components_missing_matching_expressions(
                error_msg):
            choices = [
                "Create a new management cluster",
                "Use default kuberenetes cluster found and install CAPI required components",
                "Exit"
            ]
            msg = "The default kubernetes cluster found is missing required components for a management cluster.\
                   \nDo you want to:"

            index_choice = 0
            if prompt:
                index_choice = prompt_choice_list(msg, choices)
            if index_choice == 0:
                use_new_cluster = True
            elif index_choice != 1:
                return False
        else:
            raise UnclassifiedUserFault(err) from err
    except subprocess.CalledProcessError:
        pre_prompt = """
No Kubernetes cluster was found using the default configuration.

Cluster API needs a "management cluster" to run its components.
Learn more from the Cluster API Book:
https://cluster-api.sigs.k8s.io/user/concepts.html
"""
        use_new_cluster = True
    if use_new_cluster and not create_new_management_cluster(
            cmd,
            management_cluster_name,
            resource_group_name,
            location,
            pre_prompt_text=pre_prompt,
            prompt=prompt):
        return False

    _create_azure_identity_secret(cmd)
    _install_capi_provider_components(cmd)
    return True
Exemplo n.º 8
0
def find_nodes(kubeconfig):
    command = ["kubectl", "get", "nodes", "--output", "name", "--kubeconfig", kubeconfig]
    try:
        output = subprocess.check_output(command, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
        return output.splitlines()
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault("Couldn't get nodes of workload cluster") from err
Exemplo n.º 9
0
def list_workload_clusters(cmd):
    cmd = ["kubectl", "get", "clusters", "-o", "json"]
    try:
        output = subprocess.check_output(cmd, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(cmd), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault(err)
    return json.loads(output)
Exemplo n.º 10
0
def list_workload_clusters(cmd):  # pylint: disable=unused-argument
    exit_if_no_management_cluster()
    command = ["kubectl", "get", "clusters", "-o", "json"]
    try:
        output = subprocess.check_output(command, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault("Couldn't list workload clusters") from err
    return json.loads(output)
Exemplo n.º 11
0
def try_command_with_spinner(cmd, command, spinner_begin_msg, spinner_end_msg,
                             error_msg, include_error_stdout=False):
    with Spinner(cmd, spinner_begin_msg, spinner_end_msg):
        try:
            run_shell_command(command)
        except (subprocess.CalledProcessError, FileNotFoundError) as err:
            if include_error_stdout:
                error_msg += f"\n{err.stdout}"
            raise UnclassifiedUserFault(error_msg) from err
Exemplo n.º 12
0
def _run_command(bicep_installation_path, args):
    process = subprocess.run([rf"{bicep_installation_path}"] + args,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)

    try:
        process.check_returncode()
        return process.stdout.decode("utf-8")
    except subprocess.CalledProcessError:
        raise UnclassifiedUserFault(process.stderr.decode("utf-8"))
Exemplo n.º 13
0
def _install_capz_components():
    os.environ["EXP_MACHINE_POOL"] = "true"
    os.environ["EXP_CLUSTER_RESOURCE_SET"] = "true"
    command = ["clusterctl", "init", "--infrastructure", "azure"]
    try:
        output = subprocess.check_output(command, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault(
            "Can't locate a Kubernetes cluster") from err
Exemplo n.º 14
0
def show_workload_cluster(cmd, capi_name):  # pylint: disable=unused-argument
    exit_if_no_management_cluster()
    # TODO: --output=table could print the output of `clusterctl describe` directly.
    command = ["kubectl", "get", "cluster", capi_name, "--output", "json"]
    try:
        output = subprocess.check_output(command, stderr=subprocess.STDOUT, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault("Couldn't get the workload cluster {}".format(capi_name)) from err
    return json.loads(output)
Exemplo n.º 15
0
def create_management_cluster(cmd):
    # TODO: add user confirmation
    check_preqreqs(cmd)

    command = ["clusterctl", "init", "--infrastructure", "azure"]
    try:
        output = subprocess.check_output(command, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault(
            "Can't locate a Kubernetes cluster") from err
Exemplo n.º 16
0
def delete_workload_cluster(cmd, capi_name, yes=False):
    exit_if_no_management_cluster()
    msg = 'Do you want to delete this Kubernetes cluster "{}"?'.format(capi_name)
    if not yes and not prompt_y_n(msg, default="n"):
        return
    cmd = ["kubectl", "delete", "cluster", capi_name]
    try:
        output = subprocess.check_output(cmd, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(cmd), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault("Couldn't delete workload cluster") from err
Exemplo n.º 17
0
def create_management_cluster(cmd, yes=False):
    check_prereqs(cmd)
    msg = 'Do you want to initialize Cluster API on the current cluster?'
    if not yes and not prompt_y_n(msg, default="n"):
        return

    command = ["clusterctl", "init", "--infrastructure", "azure"]
    try:
        output = subprocess.check_output(command, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault("Can't locate a Kubernetes cluster") from err
Exemplo n.º 18
0
def _install_capz_components(cmd):
    os.environ["EXP_MACHINE_POOL"] = "true"
    os.environ["EXP_CLUSTER_RESOURCE_SET"] = "true"
    with Spinner(cmd, "Initializing management cluster", "✓ Initialized management cluster"):
        command = ["clusterctl", "init", "--infrastructure", "azure"]
        try:
            # if --verbose, don't capture stderr
            stderr = None if is_verbose() else subprocess.STDOUT
            output = subprocess.check_output(command, universal_newlines=True, stderr=stderr)
            logger.info("%s returned:\n%s", " ".join(command), output)
        except subprocess.CalledProcessError as err:
            raise UnclassifiedUserFault("Can't locate a Kubernetes cluster") from err
Exemplo n.º 19
0
def show_workload_cluster(cmd, name):  # pylint: disable=unused-argument
    # TODO: --output=table should print the output of `clusterctl describe` directly.
    # command = ["clusterctl", "describe", "cluster", name]
    command = ["kubectl", "get", "cluster", name, "--output", "json"]
    try:
        output = subprocess.check_output(command,
                                         stderr=subprocess.STDOUT,
                                         universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault(err)
    return json.loads(output)
Exemplo n.º 20
0
def get_kubeconfig(capi_name):
    cmd = ["clusterctl", "get", "kubeconfig", capi_name]
    # if --verbose, don't capture stderr
    stderr = None if is_verbose() else subprocess.STDOUT
    try:
        output = subprocess.check_output(cmd, universal_newlines=True, stderr=stderr)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault("Couldn't get kubeconfig") from err
    filename = capi_name + ".kubeconfig"
    with open(filename, "w") as kubeconfig_file:
        kubeconfig_file.write(output)
    return "Wrote kubeconfig file to {} ".format(filename)
Exemplo n.º 21
0
def datamigration_register_ir(auth_key, ir_path=None):

    validate_os_env()

    if not is_user_admin():
        raise UnclassifiedUserFault(
            "Failed: You do not have Administrator rights to run this command. Please re-run this command as an Administrator!"
        )
    validate_input(auth_key)
    if ir_path is not None:
        install_gateway(ir_path)

    register_ir(auth_key)
Exemplo n.º 22
0
def update_management_cluster(cmd):
    # Check for local prerequisites
    check_preqreqs(cmd)
    cmd = [
        "clusterctl",
        "upgrade",
        "apply",
        "--management-group",
        "capi-system/cluster-api",
        "--contract",
        "v1alpha3",
    ]
    try:
        output = subprocess.check_output(cmd, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(cmd), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault(err)
Exemplo n.º 23
0
def _run_command(bicep_installation_path, args):
    process = subprocess.run([rf"{bicep_installation_path}"] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    try:
        process.check_returncode()
        command_warnings = process.stderr.decode("utf-8")
        if command_warnings:
            _logger.warning(command_warnings)
        return process.stdout.decode("utf-8")
    except subprocess.CalledProcessError:
        stderr_output = process.stderr.decode("utf-8")
        errors = []

        for line in stderr_output.splitlines():
            if re.match(_bicep_diagnostic_warning_pattern, line):
                _logger.warning(line)
            else:
                errors.append(line)

        error_msg = os.linesep.join(errors)
        raise UnclassifiedUserFault(error_msg)
Exemplo n.º 24
0
def update_management_cluster(cmd, yes=False):
    exit_if_no_management_cluster()
    msg = 'Do you want to update Cluster API components on the current cluster?'
    if not yes and not prompt_y_n(msg, default="n"):
        return
    # Check for clusterctl tool
    check_prereqs(cmd, install=yes)
    command = [
        "clusterctl",
        "upgrade",
        "apply",
        "--management-group",
        "capi-system/cluster-api",
        "--contract",
        "v1alpha3",
    ]
    try:
        output = subprocess.check_output(command, universal_newlines=True)
        logger.info("%s returned:\n%s", " ".join(command), output)
    except subprocess.CalledProcessError as err:
        raise UnclassifiedUserFault("Couldn't upgrade management cluster") from err
Exemplo n.º 25
0
def create_aks_management_cluster(cmd,
                                  cluster_name,
                                  resource_group_name=None,
                                  location=None,
                                  yes=False):
    if not resource_group_name:
        msg = "Please name the resource group for the management cluster"
        resource_group_name = get_user_prompt_or_default(msg,
                                                         cluster_name,
                                                         skip_prompt=yes)
    if not location:
        default_location = "southcentralus"
        msg = f"Please provide a location for {resource_group_name} resource group"
        location = get_user_prompt_or_default(msg,
                                              default_location,
                                              skip_prompt=yes)
    if not create_resource_group(cmd, resource_group_name, location, yes):
        return False
    command = [
        "az", "aks", "create", "-g", resource_group_name, "--name",
        cluster_name, "--generate-ssh-keys", "--network-plugin", "azure",
        "--network-policy", "calico"
    ]
    try_command_with_spinner(cmd, command,
                             "Creating Azure management cluster with AKS",
                             "✓ Created AKS management cluster",
                             "Couldn't create AKS management cluster")
    os.environ[MANAGEMENT_RG_NAME] = resource_group_name
    with Spinner(cmd, "Obtaining AKS credentials",
                 "✓ Obtained AKS credentials"):
        command = [
            "az", "aks", "get-credentials", "-g", resource_group_name,
            "--name", cluster_name
        ]
        try:
            subprocess.check_call(command, universal_newlines=True)
        except subprocess.CalledProcessError as err:
            raise UnclassifiedUserFault(
                "Couldn't get credentials for AKS management cluster") from err
    return True
Exemplo n.º 26
0
def pivot_cluster(cmd, target_cluster_kubeconfig):

    logger.warning("Starting Pivot Process")

    begin_msg = "Installing Cluster API components in target management cluster"
    end_msg = "✓ Installed Cluster API components in target management cluster"
    with Spinner(cmd, begin_msg, end_msg):
        set_azure_identity_secret_env_vars()
        _create_azure_identity_secret(cmd, target_cluster_kubeconfig)
        _install_capi_provider_components(cmd, target_cluster_kubeconfig)

    with Spinner(cmd, "Waiting for workload cluster machines to be ready",
                 "✓ Workload cluster machines are ready"):
        wait_for_machines()

    command = [
        "clusterctl", "move", "--to-kubeconfig", target_cluster_kubeconfig
    ]
    begin_msg = "Moving cluster objects into target cluster"
    end_msg = "✓ Moved cluster objects into target cluster"
    error_msg = "Could not complete clusterctl move action"
    try_command_with_spinner(cmd, command, begin_msg, end_msg, error_msg, True)

    cluster_name = find_cluster_in_current_context()
    if has_kind_prefix(cluster_name):
        delete_kind_cluster_from_current_context(cmd)
    else:
        resource_group = os.environ.get(MANAGEMENT_RG_NAME, None)
        if not resource_group:
            raise UnclassifiedUserFault(
                "Could not delete AKS management cluster, resource group missing"
            )
        delete_aks_cluster(cmd, cluster_name, resource_group)

    # Merge workload cluster kubeconfig and default kubeconfig.
    # To preverse any previous existing contexts
    merge_kubeconfig(target_cluster_kubeconfig)
    logger.warning("Completed Pivot Process")
    return True
Exemplo n.º 27
0
def create_management_cluster(cmd,
                              cluster_name=None,
                              resource_group_name=None,
                              location=None,
                              yes=False):
    check_prereqs(cmd)
    existing_cluster = find_cluster_in_current_context()
    found_cluster = False
    if existing_cluster:
        msg = f'Do you want to initialize Cluster API on the current cluster {existing_cluster}?'
        if yes or prompt_y_n(msg, default="n"):
            try:
                _find_default_cluster()
                found_cluster = True
            except subprocess.CalledProcessError as err:
                raise UnclassifiedUserFault(
                    "Can't locate a Kubernetes cluster") from err
    if not found_cluster and not create_new_management_cluster(
            cmd, cluster_name, resource_group_name, location, prompt=not yes):
        return
    set_azure_identity_secret_env_vars()
    _create_azure_identity_secret(cmd)
    _install_capi_provider_components(cmd)
Exemplo n.º 28
0
def map_azure_error_to_cli_error(azure_error):
    error_message = getattr(azure_error, "message", str(azure_error))
    if isinstance(azure_error, HttpResponseError):
        status_code = getattr(azure_error, "status_code", None)
        if status_code:
            status_code = int(status_code)
            if status_code == 400:
                return BadRequestError(error_message)
            if status_code == 401:
                return UnauthorizedError(error_message)
            if status_code == 403:
                return ForbiddenError(error_message)
            if status_code == 404:
                return ResourceNotFoundError(error_message)
            if 400 <= status_code < 500:
                return UnclassifiedUserFault(error_message)
            if 500 <= status_code < 600:
                return AzureInternalError(error_message)
        return ServiceError(error_message)
    if isinstance(azure_error, ServiceRequestError):
        return ClientRequestError(error_message)
    if isinstance(azure_error, ServiceResponseError):
        return AzureResponseError(error_message)
    return ServiceError(error_message)
Exemplo n.º 29
0
     'auto-upgrade', 'all', True)
 prompt = az_cli.config.getboolean('auto-upgrade', 'prompt',
                                   True)
 cmd = ['az', 'upgrade', '--all', str(update_all)]
 if prompt:
     from knack.prompting import verify_is_a_tty, NoTTYException  # pylint: disable=ungrouped-imports
     az_upgrade_run = True
     try:
         verify_is_a_tty()
     except NoTTYException:
         az_upgrade_run = False
         err_msg = "Unable to prompt for auto upgrade as no tty available. " \
             "Run 'az config set auto-upgrade.prompt=no' to allow auto upgrade with no prompt."
         logger.warning(err_msg)
         telemetry.set_exception(
             UnclassifiedUserFault(err_msg),
             fault_type='auto-upgrade-failed')
     else:
         upgrade_exit_code = subprocess.call(
             cmd, shell=platform.system() == 'Windows')
 else:
     import os
     devnull = open(os.devnull, 'w')
     cmd.append('-y')
     upgrade_exit_code = subprocess.call(
         cmd,
         shell=platform.system() == 'Windows',
         stdout=devnull)
 if az_upgrade_run and upgrade_exit_code != 0:
     err_msg = "Auto upgrade failed with exit code {}".format(
         exit_code)
Exemplo n.º 30
0
def get_github_access_token(cmd, scope_list=None):  # pylint: disable=unused-argument
    if scope_list:
        for scope in scope_list:
            if scope not in GITHUB_OAUTH_SCOPES:
                raise ValidationError(
                    "Requested github oauth scope is invalid")
        scope_list = ' '.join(scope_list)

    authorize_url = 'https://github.com/login/device/code'
    authorize_url_data = {
        'scope': scope_list,
        'client_id': GITHUB_OAUTH_CLIENT_ID
    }

    import requests
    import time
    from urllib.parse import parse_qs

    try:
        response = requests.post(authorize_url, data=authorize_url_data)
        parsed_response = parse_qs(response.content.decode('ascii'))

        device_code = parsed_response['device_code'][0]
        user_code = parsed_response['user_code'][0]
        verification_uri = parsed_response['verification_uri'][0]
        interval = int(parsed_response['interval'][0])
        expires_in_seconds = int(parsed_response['expires_in'][0])
        logger.warning(
            'Please navigate to %s and enter the user code %s to activate and '
            'retrieve your github personal access token', verification_uri,
            user_code)

        timeout = time.time() + expires_in_seconds
        logger.warning("Waiting up to '%s' minutes for activation",
                       str(expires_in_seconds // 60))

        confirmation_url = 'https://github.com/login/oauth/access_token'
        confirmation_url_data = {
            'client_id': GITHUB_OAUTH_CLIENT_ID,
            'device_code': device_code,
            'grant_type': 'urn:ietf:params:oauth:grant-type:device_code'
        }

        pending = True
        while pending:
            time.sleep(interval)

            if time.time() > timeout:
                raise UnclassifiedUserFault(
                    'Activation did not happen in time. Please try again')

            confirmation_response = requests.post(confirmation_url,
                                                  data=confirmation_url_data)
            parsed_confirmation_response = parse_qs(
                confirmation_response.content.decode('ascii'))

            if 'error' in parsed_confirmation_response and parsed_confirmation_response[
                    'error'][0]:
                if parsed_confirmation_response['error'][0] == 'slow_down':
                    interval += 5  # if slow_down error is received, 5 seconds is added to minimum polling interval
                elif parsed_confirmation_response['error'][
                        0] != 'authorization_pending':
                    pending = False

            if 'access_token' in parsed_confirmation_response and parsed_confirmation_response[
                    'access_token'][0]:
                return parsed_confirmation_response['access_token'][0]
    except Exception as e:
        raise CLIInternalError(
            'Error: {}. Please try again, or retrieve personal access token from the Github website'
            .format(e))

    raise UnclassifiedUserFault(
        'Activation did not happen in time. Please try again')