Пример #1
0
    def test_appending_present(self):
        base = ['foo', 'bar', 'baz']
        target = 'baz'

        retval = du.append_if(base, target)

        self.assertFalse(retval)
Пример #2
0
    def test_appending_not_present(self):
        base = ['foo', 'bar']
        target = 'baz'

        retval = du.append_if(base, target)

        self.assertIn(target, base)
        self.assertTrue(retval)
Пример #3
0
def _find_lxc_hosts(inventory):
    """Build the lxc_hosts dynamic group

    Inspect the generated inventory for nodes that host LXC containers.
    Return a list of those that match for insertion into the inventory.
    Populate the 'lxc_hosts' group with any node that matches.

    This and the populate_lxc_hosts function are split in order to be less
    coupled and more testable.

    :param inventory: The dictionary containing the Ansible inventory
    :returns: List of hostnames that are LXC hosts
    :rtype: list
    """
    lxc_host_nodes = []
    nspawn_host_nodes = []
    for host, hostvars in inventory['_meta']['hostvars'].items():
        physical_host = hostvars.get('physical_host', None)
        container_tech = hostvars.get('container_tech', 'lxc')
        hostvars['container_tech'] = container_tech

        # We want this node's "parent", so append the physical host
        if not host == physical_host:
            if container_tech == 'lxc':
                appended = du.append_if(
                    array=lxc_host_nodes,
                    item=physical_host
                )
            elif container_tech == 'nspawn':
                appended = du.append_if(
                    array=nspawn_host_nodes,
                    item=physical_host
                )
            else:
                appended = None

            if appended:
                logger.debug("%s added to lxc_hosts and nspawn_hosts group",
                             physical_host)

    return lxc_host_nodes, nspawn_host_nodes
Пример #4
0
def _parse_belongs_to(key, belongs_to, inventory):
    """Parse all items in a `belongs_to` list.

    This function assumes the key defined is a group that has child subgroups,
    *not* a group with hosts defined in the group configuration.

    :param key: ``str``  Name of key to append to a given entry
    :param belongs_to: ``list``  List of items to iterate over
    :param inventory: ``dict``  Living dictionary of inventory
    """
    for item in belongs_to:
        if key not in inventory[item]['children']:
            appended = du.append_if(array=inventory[item]['children'],
                                    item=key)
            if appended:
                logger.debug("Added %s to %s", key, item)
Пример #5
0
def user_defined_setup(config, inventory):
    """Apply user defined entries from config into inventory.

    :param config: ``dict``  User defined information
    :param inventory: ``dict``  Living dictionary of inventory
    """
    hvs = inventory['_meta']['hostvars']
    for key, value in config.items():
        if key.endswith('hosts'):
            if key not in inventory:
                logger.debug("Key %s was added to inventory", key)
                inventory[key] = {'hosts': []}

            if value is None:
                logger.debug("Key %s had no value", key)
                return

            for _key, _value in value.items():
                if _key not in hvs:
                    hvs[_key] = {}

                hvs[_key].update({
                    'ansible_host': _value['ip'],
                    'container_address': _value['ip'],
                    'is_metal': True,
                    'physical_host_group': key
                })
                logger.debug("Hostvars info updated for %s", key)

                # If the entry is missing the properties key add it.
                properties = hvs[_key].get('properties')
                if not properties or not isinstance(properties, dict):
                    hvs[_key]['properties'] = dict()

                hvs[_key]['properties'].update({'is_metal': True})

                if 'host_vars' in _value:
                    for _k, _v in _value['host_vars'].items():
                        hvs[_key][_k] = _v

                ip.USED_IPS.add(_value['ip'])
                appended = du.append_if(array=inventory[key]['hosts'],
                                        item=_key)
                if appended:
                    logger.debug("Added host %s to group %s",
                                 _key, key)
Пример #6
0
def user_defined_setup(config, inventory):
    """Apply user defined entries from config into inventory.

    :param config: ``dict``  User defined information
    :param inventory: ``dict``  Living dictionary of inventory
    """
    hvs = inventory['_meta']['hostvars']
    for key, value in config.items():
        if key.endswith('hosts'):
            if key not in inventory:
                logger.debug("Key %s was added to inventory", key)
                inventory[key] = {'hosts': []}

            if value is None:
                logger.debug("Key %s had no value", key)
                return

            for _key, _value in value.items():
                if _key not in hvs:
                    hvs[_key] = {}

                hvs[_key].update({
                    'ansible_host': _value['ip'],
                    'container_address': _value['ip'],
                    'is_metal': True,
                    'physical_host_group': key
                })
                logger.debug("Hostvars info updated for %s", key)

                # If the entry is missing the properties key add it.
                properties = hvs[_key].get('properties')
                if not properties or not isinstance(properties, dict):
                    hvs[_key]['properties'] = dict()

                hvs[_key]['properties'].update({'is_metal': True})

                if 'host_vars' in _value:
                    for _k, _v in _value['host_vars'].items():
                        hvs[_key][_k] = _v

                ip.USED_IPS.add(_value['ip'])
                appended = du.append_if(array=inventory[key]['hosts'],
                                        item=_key)
                if appended:
                    logger.debug("Added host %s to group %s", _key, key)
Пример #7
0
def _find_lxc_hosts(inventory):
    """Build the lxc_hosts dynamic group

    Inspect the generated inventory for nodes that host LXC containers.
    Return a list of those that match for insertion into the inventory.
    Populate the 'lxc_hosts' group with any node that matches.

    This and the populate_lxc_hosts function are split in order to be less
    coupled and more testable.

    :param inventory: The dictionary containing the Ansible inventory
    :returns: List of hostnames that are LXC hosts
    :rtype: list
    """
    host_nodes = []
    for host, hostvars in inventory['_meta']['hostvars'].items():
        physical_host = hostvars.get('physical_host', None)

        # We want this node's "parent", so append the physical host
        if not host == physical_host:
            appended = du.append_if(array=host_nodes, item=physical_host)
            if appended:
                logger.debug("%s added to lxc_hosts group", physical_host)
    return host_nodes
Пример #8
0
def _append_to_host_groups(inventory, container_type, assignment, host_type,
                           type_and_name, host_options):
    """Append all containers to physical (logical) groups based on host types.

    :param inventory: ``dict``  Living dictionary of inventory

    :param container_type: ``str``  Type of container
    :param assignment: ``str`` Name of container component target
    :param host_type: ``str``  Name of the host type
    :param type_and_name: ``str`` Combined name of host and container name
    """
    physical_group_type = '{}_all'.format(container_type.split('_')[0])
    if physical_group_type not in inventory:
        logger.debug("Added %s group to inventory", physical_group_type)
        inventory[physical_group_type] = {'hosts': []}

    iph = inventory[physical_group_type]['hosts']
    iah = inventory[assignment]['hosts']
    for hname, hdata in inventory['_meta']['hostvars'].items():
        is_metal = False
        properties = hdata.get('properties')
        if properties:
            is_metal = properties.get('is_metal', False)

        if 'container_types' in hdata or 'container_name' in hdata:
            if 'container_name' not in hdata:
                container = hdata['container_name'] = hname
            else:
                container = hdata['container_name']

            component = hdata.get('component')
            if container.startswith(host_type):
                if 'physical_host' not in hdata:
                    hdata['physical_host'] = host_type

                if container.startswith('{}-'.format(type_and_name)):
                    appended = du.append_if(array=iah, item=container)
                    if appended:
                        logger.debug("Added host %s to %s hosts", container,
                                     assignment)
                elif is_metal is True:
                    if component == assignment:
                        appended = du.append_if(array=iah, item=container)
                        if appended:
                            logger.debug("Added is_metal host %s to %s hosts",
                                         container, assignment)
                if container.startswith('{}-'.format(type_and_name)):
                    appended = du.append_if(array=iph, item=container)
                    if appended:
                        logger.debug("Added host %s to %s hosts", container,
                                     physical_group_type)

                elif is_metal is True:
                    if container.startswith(host_type):
                        appended = du.append_if(array=iph, item=container)
                        if appended:
                            logger.debug("Added is_metal host %s to %s hosts",
                                         container, physical_group_type)

                # Append any options in config to the host_vars of a container
                container_vars = host_options.get('container_vars')
                if isinstance(container_vars, dict):
                    for _keys, _vars in container_vars.items():
                        # Copy the options dictionary for manipulation
                        if isinstance(_vars, dict):
                            options = _vars.copy()
                        else:
                            options = _vars

                        limit = None
                        # If a limit is set use the limit string as a filter
                        # for the container name and see if it matches.
                        if isinstance(options, (str, dict, list)):
                            if 'limit_container_types' in options:
                                limit = options.pop('limit_container_types',
                                                    None)

                        if limit is None or (component and limit in component):
                            logger.debug("Set options for %s", hname)
                            hdata[_keys] = options
Пример #9
0
def _build_container_hosts(container_affinity, container_hosts, type_and_name,
                           inventory, host_type, container_type,
                           container_host_type, physical_host_type, config,
                           properties, assignment):
    """Add in all of the host associations into inventory.

    This will add in all of the hosts into the inventory based on the given
    affinity for a container component and its subsequent type groups.

    :param container_affinity: ``int`` Set the number of a given container
    :param container_hosts: ``list`` List of containers on an host
    :param type_and_name: ``str`` Combined name of host and container name
    :param inventory: ``dict``  Living dictionary of inventory
    :param host_type: ``str``  Name of the host type
    :param container_type: ``str``  Type of container
    :param container_host_type: ``str`` Type of host
    :param physical_host_type: ``str``  Name of physical host group
    :param config: ``dict``  User defined information
    :param properties: ``dict``  Container properties
    :param assignment: ``str`` Name of container component target
    """
    container_list = []
    is_metal = False
    if properties:
        is_metal = properties.get('is_metal', False)

    for make_container in range(container_affinity):
        for i in container_hosts:
            if '{}-'.format(type_and_name) in i:
                du.append_if(array=container_list, item=i)

        existing_count = len(list(set(container_list)))

        if existing_count < container_affinity:
            hostvars = inventory['_meta']['hostvars']
            container_mapping = inventory[container_type]['children']
            address = None

            if is_metal is False:
                cuuid = str(uuid.uuid4())
                cuuid = cuuid.split('-')[0]
                container_host_name = '{}-{}'.format(type_and_name, cuuid)
                logger.debug("Generated container name %s",
                             container_host_name)
                hostvars_options = hostvars[container_host_name] = {}
                if container_host_type not in inventory:
                    inventory[container_host_type] = {
                        "hosts": [],
                    }

                appended = du.append_if(
                    array=inventory[container_host_type]["hosts"],
                    item=container_host_name)

                if appended:
                    logger.debug("Added container %s to %s",
                                 container_host_name, container_host_type)

                du.append_if(array=container_hosts, item=container_host_name)
            else:
                if host_type not in hostvars:
                    hostvars[host_type] = {}

                hostvars_options = hostvars[host_type]
                container_host_name = host_type
                host_type_config = config[physical_host_type][host_type]
                address = host_type_config.get('ip')

            # Create a host types containers group and append it to inventory
            host_type_containers = '{}-host_containers'.format(host_type)
            du.append_if(array=container_mapping, item=host_type_containers)

            hostvars_options.update({
                'ansible_host': address,
                'container_address': address,
                'container_name': container_host_name,
                'physical_host': host_type,
                'physical_host_group': physical_host_type,
                'component': assignment
            })
            if 'properties' not in hostvars_options:
                hostvars_options['properties'] = properties
Пример #10
0
def _append_to_host_groups(inventory, container_type, assignment, host_type,
                           type_and_name, host_options):
    """Append all containers to physical (logical) groups based on host types.

    :param inventory: ``dict``  Living dictionary of inventory

    :param container_type: ``str``  Type of container
    :param assignment: ``str`` Name of container component target
    :param host_type: ``str``  Name of the host type
    :param type_and_name: ``str`` Combined name of host and container name
    """
    physical_group_type = '{}_all'.format(container_type.split('_')[0])
    if physical_group_type not in inventory:
        logger.debug("Added %s group to inventory", physical_group_type)
        inventory[physical_group_type] = {'hosts': []}

    iph = inventory[physical_group_type]['hosts']
    iah = inventory[assignment]['hosts']
    for hname, hdata in inventory['_meta']['hostvars'].items():
        is_metal = False
        properties = hdata.get('properties')
        if properties:
            is_metal = properties.get('is_metal', False)

        if 'container_types' in hdata or 'container_name' in hdata:
            if 'container_name' not in hdata:
                container = hdata['container_name'] = hname
            else:
                container = hdata['container_name']

            component = hdata.get('component')
            if container.startswith(host_type):
                if 'physical_host' not in hdata:
                    hdata['physical_host'] = host_type

                if container.startswith('{}-'.format(type_and_name)):
                    appended = du.append_if(array=iah, item=container)
                    if appended:
                        logger.debug("Added host %s to %s hosts",
                                     container, assignment)
                elif is_metal is True:
                    if component == assignment:
                        appended = du.append_if(array=iah, item=container)
                        if appended:
                            logger.debug("Added is_metal host %s to %s hosts",
                                         container, assignment)
                if container.startswith('{}-'.format(type_and_name)):
                    appended = du.append_if(array=iph, item=container)
                    if appended:
                        logger.debug("Added host %s to %s hosts",
                                     container, physical_group_type)

                elif is_metal is True:
                    if container.startswith(host_type):
                        appended = du.append_if(array=iph, item=container)
                        if appended:
                            logger.debug("Added is_metal host %s to %s hosts",
                                         container, physical_group_type)

                # Append any options in config to the host_vars of a container
                container_vars = host_options.get('container_vars')
                if isinstance(container_vars, dict):
                    for _keys, _vars in container_vars.items():
                        # Copy the options dictionary for manipulation
                        if isinstance(_vars, dict):
                            options = _vars.copy()
                        else:
                            options = _vars

                        limit = None
                        # If a limit is set use the limit string as a filter
                        # for the container name and see if it matches.
                        if isinstance(options, (str, dict, list)):
                            if 'limit_container_types' in options:
                                limit = options.pop(
                                    'limit_container_types', None
                                )

                        if limit is None or (component and limit in component):
                            logger.debug("Set options for %s", hname)
                            hdata[_keys] = options
Пример #11
0
def _build_container_hosts(container_affinity, container_hosts, type_and_name,
                           inventory, host_type, container_type,
                           container_host_type, physical_host_type, config,
                           properties, assignment):
    """Add in all of the host associations into inventory.

    This will add in all of the hosts into the inventory based on the given
    affinity for a container component and its subsequent type groups.

    :param container_affinity: ``int`` Set the number of a given container
    :param container_hosts: ``list`` List of containers on an host
    :param type_and_name: ``str`` Combined name of host and container name
    :param inventory: ``dict``  Living dictionary of inventory
    :param host_type: ``str``  Name of the host type
    :param container_type: ``str``  Type of container
    :param container_host_type: ``str`` Type of host
    :param physical_host_type: ``str``  Name of physical host group
    :param config: ``dict``  User defined information
    :param properties: ``dict``  Container properties
    :param assignment: ``str`` Name of container component target
    """
    container_list = []
    is_metal = False
    if properties:
        is_metal = properties.get('is_metal', False)

    for make_container in range(container_affinity):
        for i in container_hosts:
            if '{}-'.format(type_and_name) in i:
                du.append_if(array=container_list, item=i)

        existing_count = len(list(set(container_list)))

        if existing_count < container_affinity:
            hostvars = inventory['_meta']['hostvars']
            container_mapping = inventory[container_type]['children']
            address = None

            if is_metal is False:
                cuuid = str(uuid.uuid4())
                cuuid = cuuid.split('-')[0]
                container_host_name = '{}-{}'.format(type_and_name, cuuid)
                logger.debug("Generated container name %s",
                             container_host_name)
                hostvars_options = hostvars[container_host_name] = {}
                if container_host_type not in inventory:
                    inventory[container_host_type] = {
                        "hosts": [],
                    }

                appended = du.append_if(
                    array=inventory[container_host_type]["hosts"],
                    item=container_host_name
                )

                if appended:
                    logger.debug("Added container %s to %s",
                                 container_host_name, container_host_type)

                du.append_if(array=container_hosts, item=container_host_name)
            else:
                if host_type not in hostvars:
                    hostvars[host_type] = {}

                hostvars_options = hostvars[host_type]
                container_host_name = host_type
                host_type_config = config[physical_host_type][host_type]
                address = host_type_config.get('ip')

            # Create a host types containers group and append it to inventory
            host_type_containers = '{}-host_containers'.format(host_type)
            du.append_if(array=container_mapping, item=host_type_containers)

            hostvars_options.update({
                'properties': properties,
                'ansible_host': address,
                'container_address': address,
                'container_name': container_host_name,
                'physical_host': host_type,
                'physical_host_group': physical_host_type,
                'component': assignment
            })