示例#1
0
def _add_additional_networks(key, inventory, ip_q, q_name, netmask, interface,
                             bridge, net_type, net_mtu, user_config,
                             is_ssh_address, is_container_address,
                             static_routes, reference_group, address_prefix):
    """Process additional ip adds and append then to hosts as needed.

    If the host is found to be "is_metal" it will be marked as "on_metal"
    and will not have an additionally assigned IP address.

    :param key: ``str`` Component key name. This could be a group or a host
        name
    :param inventory: ``dict``  Living dictionary of inventory.
    :param ip_q: ``object`` build queue of IP addresses.
    :param q_name: ``str`` key to use in host vars for storage. May be blank.
    :param netmask: ``str`` netmask to use.
    :param interface: ``str`` interface name to set for the network.
    :param user_config: ``dict`` user defined configuration details.
    :param is_ssh_address: ``bol`` set this address as ansible_host.
    :param is_container_address: ``bol`` set this address to container_address.
    :param static_routes: ``list`` List containing static route dicts.
    :param reference_group: ``str`` group to filter membership of host against.
    :param address_prefix: ``str`` override prefix of key for network address.
    """

    base_hosts = inventory['_meta']['hostvars']
    lookup = inventory.get(key, list())

    if 'children' in lookup and lookup['children']:
        for group in lookup['children']:
            _add_additional_networks(group, inventory, ip_q, q_name, netmask,
                                     interface, bridge, net_type, net_mtu,
                                     user_config, is_ssh_address,
                                     is_container_address, static_routes,
                                     reference_group, address_prefix)

    # Make sure the lookup object has a value.
    if lookup:
        hosts = lookup.get('hosts')
        if not hosts:
            return
    else:
        return

    if address_prefix:
        old_address = '%s_address' % address_prefix
    # TODO(cloudnull) after a few releases this should be removed.
    elif q_name:
        old_address = '{}_address'.format(q_name)
    else:
        old_address = '{}_address'.format(interface)

    for container_host in hosts:
        container = base_hosts[container_host]

        physical_host = container.get('physical_host')
        if (reference_group and physical_host
                not in inventory.get(reference_group).get('hosts')):
            continue

        # TODO(cloudnull) after a few releases this should be removed.
        # This removes the old container network value that now serves purpose.
        container.pop('container_network', None)

        if 'container_networks' in container:
            networks = container['container_networks']
        else:
            networks = container['container_networks'] = dict()

        is_metal = False
        properties = container.get('properties')
        if properties:
            is_metal = properties.get('is_metal', False)

        _network = network_entry(is_metal, interface, bridge, net_type,
                                 net_mtu)
        # This should convert found addresses based on q_name + "_address"
        #  and then build the network if its not found.
        if not is_metal and (old_address not in networks
                             or networks[old_address] != _network):
            network = networks[old_address] = _network
            if old_address in container and container[old_address]:
                network['address'] = container.pop(old_address)
            elif not is_metal:
                address = ip.get_ip_address(name=q_name, ip_q=ip_q)
                if address:
                    network['address'] = address

            network['netmask'] = netmask
        elif is_metal:
            network = networks[old_address] = _network
            network['netmask'] = netmask
            if is_ssh_address or is_container_address:
                # Container physical host group
                cphg = container.get('physical_host_group')

                # user_config data from the container physical host group
                if user_config[cphg].get(container_host) is not None:
                    phg = user_config[cphg][container_host]
                else:
                    phg = user_config[cphg][physical_host]
                network['address'] = phg['ip']

        if is_ssh_address is True:
            container['ansible_host'] = networks[old_address]['address']

        if is_container_address is True:
            container['container_address'] = networks[old_address]['address']

        if static_routes:
            # NOTE: networks[old_address]['static_routes'] will get
            #       regenerated on each run
            networks[old_address]['static_routes'] = []
            for route in static_routes:
                # only add static routes if they are specified correctly;
                # that is, the key and a value must be present. This doesn't
                # ensure that the values provided are routable, just that
                # they are not empty.
                cidr_present = route.get('cidr', False)
                gateway_present = route.get('gateway', False)

                if not (cidr_present and gateway_present):
                    raise MissingStaticRouteInfo(q_name)
                networks[old_address]['static_routes'].append(route)
def _add_additional_networks(key, inventory, ip_q, q_name, netmask, interface,
                             bridge, net_type, net_mtu, user_config,
                             is_ssh_address, is_container_address,
                             static_routes):
    """Process additional ip adds and append then to hosts as needed.

    If the host is found to be "is_metal" it will be marked as "on_metal"
    and will not have an additionally assigned IP address.

    :param key: ``str`` Component key name. This could be a group or a host
        name
    :param inventory: ``dict``  Living dictionary of inventory.
    :param ip_q: ``object`` build queue of IP addresses.
    :param q_name: ``str`` key to use in host vars for storage. May be blank.
    :param netmask: ``str`` netmask to use.
    :param interface: ``str`` interface name to set for the network.
    :param user_config: ``dict`` user defined configuration details.
    :param is_ssh_address: ``bol`` set this address as ansible_host.
    :param is_container_address: ``bol`` set this address to container_address.
    :param static_routes: ``list`` List containing static route dicts.
    """

    base_hosts = inventory['_meta']['hostvars']
    lookup = inventory.get(key, list())

    if 'children' in lookup and lookup['children']:
        for group in lookup['children']:
            _add_additional_networks(
                group,
                inventory,
                ip_q,
                q_name,
                netmask,
                interface,
                bridge,
                net_type,
                net_mtu,
                user_config,
                is_ssh_address,
                is_container_address,
                static_routes
            )

    # Make sure the lookup object has a value.
    if lookup:
        hosts = lookup.get('hosts')
        if not hosts:
            return
    else:
        return

    # TODO(cloudnull) after a few releases this should be removed.
    if q_name:
        old_address = '{}_address'.format(q_name)
    else:
        old_address = '{}_address'.format(interface)

    for container_host in hosts:
        container = base_hosts[container_host]

        # TODO(cloudnull) after a few releases this should be removed.
        # This removes the old container network value that now serves purpose.
        container.pop('container_network', None)

        if 'container_networks' in container:
            networks = container['container_networks']
        else:
            networks = container['container_networks'] = dict()

        is_metal = False
        properties = container.get('properties')
        if properties:
            is_metal = properties.get('is_metal', False)

        # This should convert found addresses based on q_name + "_address"
        #  and then build the network if its not found.
        if not is_metal and old_address not in networks:
            network = networks[old_address] = network_entry(
                is_metal,
                interface,
                bridge,
                net_type,
                net_mtu
            )
            if old_address in container and container[old_address]:
                network['address'] = container.pop(old_address)
            elif not is_metal:
                address = ip.get_ip_address(name=q_name, ip_q=ip_q)
                if address:
                    network['address'] = address

            network['netmask'] = netmask
        elif is_metal:
            network = networks[old_address] = network_entry(
                is_metal,
                interface,
                bridge,
                net_type,
                net_mtu
            )
            network['netmask'] = netmask
            if is_ssh_address or is_container_address:
                # Container physical host group
                cphg = container.get('physical_host_group')

                # user_config data from the container physical host group
                phg = user_config[cphg][container_host]
                network['address'] = phg['ip']

        if is_ssh_address is True:
            container['ansible_host'] = networks[old_address]['address']

        if is_container_address is True:
            container['container_address'] = networks[old_address]['address']

        if static_routes:
            # NOTE: networks[old_address]['static_routes'] will get
            #       regenerated on each run
            networks[old_address]['static_routes'] = []
            for route in static_routes:
                # only add static routes if they are specified correctly;
                # that is, the key and a value must be present. This doesn't
                # ensure that the values provided are routable, just that
                # they are not empty.
                cidr_present = route.get('cidr', False)
                gateway_present = route.get('gateway', False)

                if not (cidr_present and gateway_present):
                    raise MissingStaticRouteInfo(q_name)
                networks[old_address]['static_routes'].append(route)