Exemplo n.º 1
0
def _ask_for_subnets(subnet_list):
    master_subnet_id = prompt_iterable("Master Subnet ID", subnet_list)
    compute_subnet_id = prompt_iterable("Compute Subnet ID",
                                        subnet_list,
                                        default_value=master_subnet_id)
    vpc_parameters = {"master_subnet_id": master_subnet_id}

    if master_subnet_id != compute_subnet_id:
        vpc_parameters["compute_subnet_id"] = compute_subnet_id

    return vpc_parameters
Exemplo n.º 2
0
def _choose_network_configuration(cluster_config):
    if cluster_config.scheduler == "awsbatch":
        return PublicPrivateNetworkConfig()
    azs_for_head_node_type = get_supported_az_for_one_instance_type(
        cluster_config.head_node_instance_type)
    azs_for_compute_type = get_supported_az_for_one_instance_type(
        cluster_config.compute_instance_type)
    common_availability_zones = set(azs_for_head_node_type) & set(
        azs_for_compute_type)

    if not common_availability_zones:
        # Automate subnet creation only allows subnets to reside in a single az.
        # But user can bypass it by using manual subnets creation during configure or modify the config file directly.
        print(
            "Error: There is no single availability zone offering head node and compute in current region.\n"
            "To create your cluster, make sure you have a subnet for head node in {0}"
            ", and a subnet for compute nodes in {1}. Then run pcluster configure again"
            "and avoid using Automate VPC/Subnet creation.".format(
                azs_for_head_node_type, azs_for_compute_type))
        print("Exiting...")
        sys.exit(1)
    target_type = prompt_iterable(
        "Network Configuration",
        options=[
            configuration.value.config_type
            for configuration in NetworkConfiguration
        ],
        default_value=PublicPrivateNetworkConfig().config_type,
    )

    network_configuration = next(
        configuration.value for configuration in NetworkConfiguration
        if configuration.value.config_type == target_type)
    network_configuration.availability_zones = common_availability_zones
    return network_configuration
Exemplo n.º 3
0
def _create_vpc_parameters(vpc_section,
                           scheduler,
                           min_subnet_size,
                           automate_vpc_creation=True):
    vpc_parameters = {}
    min_subnet_size = int(min_subnet_size)
    if automate_vpc_creation:
        vpc_parameters.update(
            automate_vpc_with_subnet_creation(
                _choose_network_configuration(scheduler), min_subnet_size))
    else:
        vpc_and_subnets = _get_vpcs_and_subnets()
        vpc_list = vpc_and_subnets["vpc_list"]
        if not vpc_list:
            print(
                "There are no VPC for the given region. Starting automatic creation of VPC and subnets..."
            )
            vpc_parameters.update(
                automate_vpc_with_subnet_creation(
                    _choose_network_configuration(scheduler), min_subnet_size))
        else:
            vpc_id = prompt_iterable("VPC ID", vpc_list,
                                     vpc_section.get_param_value("vpc_id"))
            vpc_parameters["vpc_id"] = vpc_id
            subnet_list = vpc_and_subnets["vpc_subnets"][vpc_id]
            if not subnet_list or (prompt("Automate Subnet creation? (y/n)",
                                          lambda x: x in ("y", "n"),
                                          default_value="y") == "y"):
                vpc_parameters.update(
                    automate_subnet_creation(
                        vpc_id, _choose_network_configuration(scheduler),
                        min_subnet_size))
            else:
                vpc_parameters.update(_ask_for_subnets(subnet_list))
    return vpc_parameters
Exemplo n.º 4
0
 def prompt_os(self):
     """Ask for os, if necessary."""
     if not self.is_aws_batch:
         self.base_os = prompt_iterable(
             "Operating System",
             get_supported_os_for_scheduler(self.scheduler),
             default_value=self.cluster_section.get_param_value("base_os"),
         )
Exemplo n.º 5
0
def _create_vpc_parameters(vpc_section, cluster_config):
    vpc_parameters = {}
    min_subnet_size = int(cluster_config.max_cluster_size)
    automate_vpc_creation = prompt("Automate VPC creation? (y/n)",
                                   lambda x: x in ("y", "n"),
                                   default_value="n") == "y"
    if automate_vpc_creation:
        vpc_parameters.update(
            automate_vpc_with_subnet_creation(
                _choose_network_configuration(cluster_config),
                min_subnet_size))
    else:
        vpc_and_subnets = _get_vpcs_and_subnets()
        vpc_list = vpc_and_subnets["vpc_list"]
        if not vpc_list:
            print(
                "There are no VPC for the given region. Starting automatic creation of VPC and subnets..."
            )
            vpc_parameters.update(
                automate_vpc_with_subnet_creation(
                    _choose_network_configuration(cluster_config),
                    min_subnet_size))
        else:
            default_vpc = vpc_section.get_param_value("vpc_id")
            vpc_id = prompt_iterable("VPC ID",
                                     vpc_list,
                                     default_value=default_vpc)
            vpc_parameters["vpc_id"] = vpc_id
            subnet_list = vpc_and_subnets["vpc_subnets"][vpc_id]
            qualified_head_node_subnets = _filter_subnets_offering_instance_type(
                subnet_list, cluster_config.head_node_instance_type)
            if cluster_config.scheduler != "awsbatch":
                qualified_compute_subnets = _filter_subnets_offering_instance_type(
                    subnet_list, cluster_config.compute_instance_type)
            else:
                # Special case of awsbatch, where compute instance type is not specified
                qualified_compute_subnets = subnet_list
            if (not qualified_head_node_subnets
                    or not qualified_compute_subnets
                    or (prompt("Automate Subnet creation? (y/n)",
                               lambda x: x in ("y", "n"),
                               default_value="y") == "y")):
                # Start auto subnets creation in the absence of qualified subnets.
                # Otherwise, user selects between manual and automate subnets creation
                if not qualified_head_node_subnets or not qualified_compute_subnets:
                    print(
                        "There are no qualified subnets. Starting automatic creation of subnets..."
                    )
                vpc_parameters.update(
                    automate_subnet_creation(
                        vpc_id, _choose_network_configuration(cluster_config),
                        min_subnet_size))
            else:
                vpc_parameters.update(
                    _ask_for_subnets(subnet_list, vpc_section,
                                     qualified_head_node_subnets,
                                     qualified_compute_subnets))
    return vpc_parameters
Exemplo n.º 6
0
def _prompt_for_subnet(default_subnet, all_subnets, qualified_subnets,
                       message):
    total_omitted_subnets = len(all_subnets) - len(qualified_subnets)
    if total_omitted_subnets > 0:
        print("Note:  {0} subnet(s) is/are not listed, "
              "because the instance type is not in their availability zone(s)".
              format(total_omitted_subnets))
    return prompt_iterable(message,
                           qualified_subnets,
                           default_value=default_subnet)
Exemplo n.º 7
0
def _choose_network_configuration(scheduler):
    if scheduler == "awsbatch":
        return PublicPrivateNetworkConfig()
    target_type = prompt_iterable(
        "Network Configuration",
        options=[
            configuration.value.config_type
            for configuration in NetworkConfiguration
        ],
        default_value=PublicPrivateNetworkConfig().config_type,
    )

    return next(configuration.value for configuration in NetworkConfiguration
                if configuration.value.config_type == target_type)
Exemplo n.º 8
0
def _ask_for_subnets(subnet_list, vpc_section):
    available_subnets = [subnet_entry[0] for subnet_entry in subnet_list]
    default_master_subnet = vpc_section.get_param_value("master_subnet_id")
    master_subnet_id = prompt_iterable(
        "Master Subnet ID",
        subnet_list,
        default_value=default_master_subnet
        if default_master_subnet in available_subnets else None,
    )

    default_compute_subnet = vpc_section.get_param_value("compute_subnet_id")
    compute_subnet_id = prompt_iterable(
        "Compute Subnet ID",
        subnet_list,
        default_value=(default_compute_subnet if default_compute_subnet
                       in available_subnets else None) or master_subnet_id,
    )
    vpc_parameters = {"master_subnet_id": master_subnet_id}

    if master_subnet_id != compute_subnet_id:
        vpc_parameters["compute_subnet_id"] = compute_subnet_id

    return vpc_parameters
Exemplo n.º 9
0
def configure(args):
    # Check for invalid path (eg. a directory)
    if args.config_file and os.path.exists(
            args.config_file) and not os.path.isfile(args.config_file):
        error("Invalid configuration file path: {0}".format(args.config_file))

    pcluster_config = PclusterConfig(config_file=args.config_file,
                                     fail_on_error=False,
                                     auto_refresh=False)

    # FIXME: Overriding HIT config files is currently not supported.
    if pcluster_config.cluster_model == ClusterModel.HIT:
        error(
            "Configuration in file {0} cannot be overwritten. Please specify a different file path"
            .format(pcluster_config.config_file))

    if os.path.exists(pcluster_config.config_file):
        msg = "WARNING: Configuration file {0} will be overwritten."
    else:
        msg = "INFO: Configuration file {0} will be written."
    print(msg.format(pcluster_config.config_file))
    print("Press CTRL-C to interrupt the procedure.\n\n")

    if not args.region:
        # Use built in boto regions as an available option
        available_regions = get_regions()
        default_region = pcluster_config.get_section("aws").get_param_value(
            "aws_region_name")
        aws_region_name = prompt_iterable("AWS Region ID",
                                          available_regions,
                                          default_value=default_region)
        # Set provided region into os environment for suggestions and validations from here on
        os.environ["AWS_DEFAULT_REGION"] = aws_region_name
    else:
        aws_region_name = args.region

    cluster_section = pcluster_config.get_section("cluster")

    global_config = pcluster_config.get_section("global")
    cluster_label = global_config.get_param_value("cluster_template")

    vpc_section = pcluster_config.get_section("vpc")
    vpc_label = vpc_section.label

    # Get the key name from the current region, if any
    available_keys = _get_keys()
    default_key = cluster_section.get_param_value("key_name")
    key_name = prompt_iterable("EC2 Key Pair Name",
                               available_keys,
                               default_value=default_key)

    scheduler = prompt_iterable(
        "Scheduler",
        get_supported_schedulers(),
        default_value=cluster_section.get_param_value("scheduler"))
    cluster_config = ClusterConfigureHelper(cluster_section, scheduler)
    cluster_config.prompt_os()
    cluster_config.prompt_cluster_size()
    cluster_config.prompt_instance_types()

    vpc_parameters = _create_vpc_parameters(vpc_section, cluster_config)
    # Here is the end of prompt. Code below assembles config and write to file

    cluster_parameters = {"key_name": key_name, "scheduler": scheduler}
    cluster_parameters.update(cluster_config.get_scheduler_parameters())

    # Remove parameters from the past configuration that can conflict with the user's choices.
    _reset_config_params(cluster_section,
                         cluster_config.get_parameters_to_reset())
    _reset_config_params(
        vpc_section,
        ("compute_subnet_id", "use_public_ips", "compute_subnet_cidr"))

    # Update configuration values according to user's choices
    pcluster_config.region = aws_region_name

    cluster_section.label = cluster_label
    for param_key, param_value in cluster_parameters.items():
        param = cluster_section.get_param(param_key)
        param.value = param.get_value_from_string(param_value)

    vpc_section.label = vpc_label
    for param_key, param_value in vpc_parameters.items():
        param = vpc_section.get_param(param_key)
        param.value = param.get_value_from_string(param_value)

    # Update internal params according to provided parameters and enable auto-refresh before eventual hit conversion
    pcluster_config.refresh()
    pcluster_config.auto_refresh = True

    # Convert file if needed
    HitConverter(pcluster_config).convert(prepare_to_file=True)

    # Update config file by overriding changed settings
    pcluster_config.to_file()
    print("Configuration file written to {0}".format(
        pcluster_config.config_file))
    print(
        "You can edit your configuration file or simply run 'pcluster create -c {0} cluster-name' "
        "to create your cluster".format(pcluster_config.config_file))
Exemplo n.º 10
0
def configure(args):
    # Check for invalid path (eg. a directory)
    if args.config_file and os.path.exists(
            args.config_file) and not os.path.isfile(args.config_file):
        error("Invalid configuration file path: {0}".format(args.config_file))

    pcluster_config = PclusterConfig(config_file=args.config_file,
                                     fail_on_error=False)

    if os.path.exists(pcluster_config.config_file):
        msg = "WARNING: Configuration file {0} will be overwritten."
    else:
        msg = "INFO: Configuration file {0} will be written."
    print(msg.format(pcluster_config.config_file))
    print("Press CTRL-C to interrupt the procedure.\n\n")

    cluster_section = pcluster_config.get_section("cluster")

    global_config = pcluster_config.get_section("global")
    cluster_label = global_config.get_param_value("cluster_template")

    vpc_section = pcluster_config.get_section("vpc")
    vpc_label = vpc_section.label

    # Use built in boto regions as an available option
    available_regions = get_regions()
    default_region = pcluster_config.get_section("aws").get_param_value(
        "aws_region_name")
    aws_region_name = prompt_iterable(
        "AWS Region ID",
        available_regions,
        default_value=default_region
        if default_region in available_regions else None,
    )
    # Set provided region into os environment for suggestions and validations from here on
    os.environ["AWS_DEFAULT_REGION"] = aws_region_name

    # Get the key name from the current region, if any
    available_keys = _get_keys()
    default_key = cluster_section.get_param_value("key_name")
    key_name = prompt_iterable(
        "EC2 Key Pair Name",
        available_keys,
        default_value=default_key if default_key in available_keys else None)

    scheduler = prompt_iterable(
        "Scheduler",
        get_supported_schedulers(),
        default_value=cluster_section.get_param_value("scheduler"))
    scheduler_handler = SchedulerHandler(cluster_section, scheduler)

    scheduler_handler.prompt_os()
    scheduler_handler.prompt_cluster_size()

    master_instance_type = prompt(
        "Master instance type",
        lambda x: x in get_supported_instance_types(),
        default_value=cluster_section.get_param_value("master_instance_type"),
    )

    scheduler_handler.prompt_compute_instance_type()

    automate_vpc = prompt("Automate VPC creation? (y/n)",
                          lambda x: x in ("y", "n"),
                          default_value="n") == "y"

    vpc_parameters = _create_vpc_parameters(vpc_section,
                                            scheduler,
                                            scheduler_handler.max_cluster_size,
                                            automate_vpc_creation=automate_vpc)
    cluster_parameters = {
        "key_name": key_name,
        "scheduler": scheduler,
        "master_instance_type": master_instance_type
    }
    cluster_parameters.update(scheduler_handler.get_scheduler_parameters())

    # Remove parameters from the past configuration that can conflict with the user's choices.
    _reset_config_params(cluster_section,
                         scheduler_handler.get_parameters_to_reset())
    _reset_config_params(
        vpc_section,
        ("compute_subnet_id", "use_public_ips", "compute_subnet_cidr"))

    # Update configuration values according to user's choices
    pcluster_config.region = aws_region_name

    cluster_section.label = cluster_label
    for param_key, param_value in cluster_parameters.items():
        param = cluster_section.get_param(param_key)
        param.value = param.get_value_from_string(param_value)

    vpc_section.label = vpc_label
    for param_key, param_value in vpc_parameters.items():
        param = vpc_section.get_param(param_key)
        param.value = param.get_value_from_string(param_value)

    # Update config file by overriding changed settings
    pcluster_config.to_file()
    print("Configuration file written to {0}".format(
        pcluster_config.config_file))
    print(
        "You can edit your configuration file or simply run 'pcluster create -c {0} cluster-name' "
        "to create your cluster".format(pcluster_config.config_file))