Ejemplo n.º 1
0
def get_rack_ip_for_subnet(version, cidr, interface):
    """
    Return the IP address on this rack controller.

    First the code will try to find an IP address that is in the cidr, but if
    not it will use the first IP address on the interface (to support
    VLAN relay).
    """
    cidr = IPNetwork(cidr)
    if interface:
        ip_addresses = [
            IPAddress(addr)
            for addr in net_utils.get_all_addresses_for_interface(interface)
        ]
    else:
        ip_addresses = [
            IPAddress(addr)
            for addr in net_utils.get_all_interface_addresses()
        ]
    for ip_addr in ip_addresses:
        if ip_addr in cidr:
            return ip_addr
    for ip_addr in ip_addresses:
        if ip_addr.version == version:
            return ip_addr
    return None
Ejemplo n.º 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 = 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
Ejemplo n.º 3
0
 def _getListenAddresses(self, port):
     """Return list of tuple (address, port) for the addresses the worker
     is listening on."""
     addresses = get_all_interface_source_addresses()
     if addresses:
         return set((addr, port) for addr in addresses)
     # There are no non-loopback addresses, so return loopback
     # address as a fallback.
     loopback_addresses = set()
     for addr in get_all_interface_addresses():
         ipaddr = IPAddress(addr)
         if ipaddr.is_link_local():
             continue  # Don't advertise link-local addresses.
         if ipaddr.is_loopback():
             loopback_addresses.add((addr, port))
     return loopback_addresses
Ejemplo n.º 4
0
    def test_rpc_info_when_rpc_advertise_running(self):
        region = factory.make_RegionController()
        self.useFixture(MAASIDFixture(region.system_id))
        region.owner = factory.make_admin()
        region.save()
        self.useFixture(RegionEventLoopFixture("rpc", "rpc-advertise"))

        eventloop.start().wait(5)
        self.addCleanup(lambda: eventloop.reset().wait(5))

        getServiceNamed = eventloop.services.getServiceNamed

        @wait_for(5)
        @inlineCallbacks
        def wait_for_startup():
            # Wait for the rpc and the rpc-advertise services to start.
            yield getServiceNamed("rpc").starting
            yield getServiceNamed("rpc-advertise").starting
            # Force an update, because it's very hard to track when the
            # first iteration of the rpc-advertise service has completed.
            yield getServiceNamed("rpc-advertise")._tryUpdate()

        wait_for_startup()

        response = self.client.get(reverse('rpc-info'))

        self.assertEqual("application/json", response["Content-Type"])
        info = json.loads(response.content.decode("unicode_escape"))
        self.assertThat(info, KeysEqual("eventloops"))
        self.assertThat(
            info["eventloops"],
            MatchesDict({
                # Each entry in the endpoints dict is a mapping from an
                # event loop to a list of (host, port) tuples. Each tuple is
                # a potential endpoint for connecting into that event loop.
                eventloop.loop.name:
                MatchesSetwise(*(MatchesListwise((Equals(addr), is_valid_port))
                                 for addr in get_all_interface_addresses()
                                 if not IPAddress(addr).is_link_local()
                                 and not IPAddress(addr).is_loopback())),
            }))
Ejemplo n.º 5
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(),
    }

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

    shared_networks = _process_network_parameters_v6(rack_addrs,
                                                     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
Ejemplo n.º 6
0
    def updateServers(self):
        """Run a server on every interface.

        For each configured network interface this will start a TFTP
        server. If called later it will bring up servers on newly
        configured interfaces and bring down servers on deconfigured
        interfaces.
        """
        addrs_established = set(service.name for service in self.getServers())
        addrs_desired = set(get_all_interface_addresses())

        for address in addrs_desired - addrs_established:
            if not IPAddress(address).is_link_local():
                tftp_service = UDPServer(
                    self.port, TransferTimeTrackingTFTP(self.backend),
                    interface=address)
                tftp_service.setName(address)
                tftp_service.setServiceParent(self)

        for address in addrs_established - addrs_desired:
            tftp_service = self.getServiceNamed(address)
            tftp_service.disownServiceParent()