Пример #1
0
def get_config_v6(template_name: str, global_dhcp_snippets: Sequence[dict],
                  failover_peers: Sequence[dict],
                  shared_networks: Sequence[dict], hosts: Sequence[dict],
                  omapi_key: str) -> str:
    """Return a DHCP config file based on the supplied parameters.

    :param template_name: Template file name: `dhcpd6.conf.template` for the
        IPv6 template.
    :return: A full configuration, as a string.
    """
    platform_codename = linux_distribution()[2]
    template = load_template('dhcp', template_name)
    # Helper functions to stuff into the template namespace.
    helpers = {
        "oneline": normalise_whitespace,
        "commalist": normalise_any_iterable_to_comma_list,
        "quoted_commalist": normalise_any_iterable_to_quoted_comma_list,
        "running_in_snap": snappy.running_in_snap(),
    }

    shared_networks = _process_network_parameters_v6(failover_peers,
                                                     shared_networks)

    try:
        return template.substitute(global_dhcp_snippets=global_dhcp_snippets,
                                   hosts=hosts,
                                   failover_peers=failover_peers,
                                   shared_networks=shared_networks,
                                   platform_codename=platform_codename,
                                   omapi_key=omapi_key,
                                   **helpers)
    except (KeyError, NameError) as error:
        raise DHCPConfigError(
            "Failed to render DHCP configuration.") from error
Пример #2
0
def get_config_v4(
    template_name: str,
    global_dhcp_snippets: Sequence[dict],
    failover_peers: Sequence[dict],
    shared_networks: Sequence[dict],
    hosts: Sequence[dict],
    omapi_key: str,
) -> str:
    """Return a DHCP config file based on the supplied parameters.

    :param template_name: Template file name: `dhcpd.conf.template` for the
        IPv4 template.
    :return: A full configuration, as a string.
    """
    platform_codename = lsb_release()["codename"]
    template = load_template("dhcp", template_name)
    dhcp_socket = get_maas_data_path("dhcpd.sock")

    # Helper functions to stuff into the template namespace.
    helpers = {
        "oneline": normalise_whitespace,
        "commalist": normalise_any_iterable_to_comma_list,
        "quoted_commalist": normalise_any_iterable_to_quoted_comma_list,
        "running_in_snap": snappy.running_in_snap(),
    }

    for shared_network in shared_networks:
        interface = shared_network.get("interface", None)
        for subnet in shared_network["subnets"]:
            rack_ip = get_rack_ip_for_subnet(
                4, subnet["subnet_cidr"], interface
            )
            if rack_ip is not None:
                subnet["next_server"] = rack_ip
                subnet["bootloader"] = compose_conditional_bootloader(
                    False, rack_ip
                )
            ntp_servers = subnet["ntp_servers"]  # Is a list.
            ntp_servers_ipv4, ntp_servers_ipv6 = _get_addresses(*ntp_servers)
            subnet["ntp_servers_ipv4"] = ", ".join(ntp_servers_ipv4)
            subnet["ntp_servers_ipv6"] = ", ".join(ntp_servers_ipv6)

    try:
        return template.substitute(
            global_dhcp_snippets=global_dhcp_snippets,
            hosts=hosts,
            failover_peers=failover_peers,
            shared_networks=shared_networks,
            platform_codename=platform_codename,
            omapi_key=omapi_key,
            dhcp_helper=(get_path("/usr/sbin/maas-dhcp-helper")),
            dhcp_socket=dhcp_socket,
            **helpers
        )
    except (KeyError, NameError) as error:
        raise DHCPConfigError(
            "Failed to render DHCP configuration."
        ) from error
Пример #3
0
def get_config_v4(template_name: str, global_dhcp_snippets: Sequence[dict],
                  failover_peers: Sequence[dict],
                  shared_networks: Sequence[dict], hosts: Sequence[dict],
                  omapi_key: str) -> str:
    """Return a DHCP config file based on the supplied parameters.

    :param template_name: Template file name: `dhcpd.conf.template` for the
        IPv4 template.
    :return: A full configuration, as a string.
    """
    platform_codename = linux_distribution()[2]
    template = load_template('dhcp', template_name)
    dhcp_socket = get_data_path('/var/lib/maas/dhcpd.sock')

    # Helper functions to stuff into the template namespace.
    helpers = {
        "oneline": normalise_whitespace,
        "commalist": normalise_any_iterable_to_comma_list,
        "quoted_commalist": normalise_any_iterable_to_quoted_comma_list,
        "running_in_snap": snappy.running_in_snap(),
    }

    rack_addrs = [
        IPAddress(addr) for addr in net_utils.get_all_interface_addresses()
    ]

    for shared_network in shared_networks:
        for subnet in shared_network["subnets"]:
            cidr = IPNetwork(subnet['subnet_cidr'])
            rack_ips = [
                str(rack_addr) for rack_addr in rack_addrs if rack_addr in cidr
            ]
            if len(rack_ips) > 0:
                subnet["next_server"] = rack_ips[0]
                subnet["bootloader"] = compose_conditional_bootloader(
                    False, rack_ips[0])
            ntp_servers = subnet["ntp_servers"]  # Is a list.
            ntp_servers_ipv4, ntp_servers_ipv6 = _get_addresses(*ntp_servers)
            subnet["ntp_servers_ipv4"] = ", ".join(ntp_servers_ipv4)
            subnet["ntp_servers_ipv6"] = ", ".join(ntp_servers_ipv6)

    try:
        return template.substitute(
            global_dhcp_snippets=global_dhcp_snippets,
            hosts=hosts,
            failover_peers=failover_peers,
            shared_networks=shared_networks,
            platform_codename=platform_codename,
            omapi_key=omapi_key,
            dhcp_helper=(get_path('/usr/sbin/maas-dhcp-helper')),
            dhcp_socket=dhcp_socket,
            **helpers)
    except (KeyError, NameError) as error:
        raise DHCPConfigError(
            "Failed to render DHCP configuration.") from error
Пример #4
0
def set_up_options_conf(overwrite=True, **kwargs):
    """Write out the named.conf.options.inside.maas file.

    This file should be included by the top-level named.conf.options
    inside its 'options' block.  MAAS cannot write the options file itself,
    so relies on either the DNSFixture in the test suite, or the packaging.
    Both should set that file up appropriately to include our file.
    """
    template = load_template("dns", "named.conf.options.inside.maas.template")

    # Make sure "upstream_dns" is set at least to None. It's a special piece
    # of config and we don't want to require that every call site has to
    # specify it. If it's not set, the substitution will fail with the default
    # template that uses this value.
    kwargs.setdefault("upstream_dns")
    kwargs.setdefault("dnssec_validation", "auto")

    # Parse the options file and make sure MAAS doesn't define any options
    # that the user has already customized.
    allow_user_override_options = [
        "allow-query",
        "allow-recursion",
        "allow-query-cache",
    ]

    try:
        parsed_options = read_isc_file(
            compose_bind_config_path(NAMED_CONF_OPTIONS)
        )
    except IOError:
        parsed_options = {}

    options = parsed_options.get("options", {})
    for option in allow_user_override_options:
        kwargs["upstream_" + option.replace("-", "_")] = option in options

    try:
        rendered = template.substitute(kwargs)
    except NameError as error:
        raise DNSConfigFail(*error.args)
    else:
        # The rendered configuration is Unicode text but should contain only
        # ASCII characters. Non-ASCII records should have been treated using
        # the rules for IDNA (Internationalized Domain Names in Applications).
        rendered = rendered.encode("ascii")

    target_path = compose_config_path(MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME)
    atomic_write(rendered, target_path, overwrite=overwrite, mode=0o644)
Пример #5
0
def render_dns_template(template_name, *parameters):
    """Generate contents for a DNS configuration or zone file.

    :param template_name: Name of the template file that should be rendered.
        It must be in provisioningserver/templates/dns/.
    :param parameters: One or more dicts of paramaters to be passed to the
        template.  Each adds to (and may overwrite) the previous ones.
    """
    template = load_template('dns', template_name)
    combined_params = {}
    for params_dict in parameters:
        combined_params.update(params_dict)
    try:
        return template.substitute(combined_params)
    except NameError as error:
        raise DNSConfigFail(*error.args)
Пример #6
0
    def _configure(self, upstream_http):
        """Update the HTTP configuration for the rack."""
        template = load_template('http', 'rackd.nginx.conf.template')
        try:
            rendered = template.substitute({
                'upstream_http':
                list(sorted(upstream_http)),
                'resource_root':
                self._resource_root,
            })
        except NameError as error:
            raise HTTPConfigFail(*error.args)
        else:
            # The rendered configuration is Unicode text but should contain
            # only ASCII characters.
            rendered = rendered.encode("ascii")

        target_path = compose_http_config_path('rackd.nginx.conf')
        os.makedirs(os.path.dirname(target_path), exist_ok=True)
        atomic_write(rendered, target_path, overwrite=True, mode=0o644)
Пример #7
0
    def _configure(self, upstream_http):
        """Update the HTTP configuration for the rack."""
        template = load_template("http", "rackd.nginx.conf.template")
        try:
            rendered = template.substitute({
                "upstream_http":
                list(sorted(upstream_http)),
                "resource_root":
                self._resource_root,
                "machine_resources":
                os.path.join(snappy.get_snap_path(), "usr/share/maas") if
                (snappy.running_in_snap()) else "/usr/share/maas",
            })
        except NameError as error:
            raise HTTPConfigFail(*error.args)
        else:
            # The rendered configuration is Unicode text but should contain
            # only ASCII characters.
            rendered = rendered.encode("ascii")

        target_path = compose_http_config_path("rackd.nginx.conf")
        os.makedirs(os.path.dirname(target_path), exist_ok=True)
        atomic_write(rendered, target_path, overwrite=True, mode=0o644)