Builds an IP address management (IPAM) config dictionary

def create_ipam_config(*pools, **kwargs):
    '''
    Builds an IP address management (IPAM) config dictionary
    '''
    kwargs = salt.utils.args.clean_kwargs(**kwargs)

    try:
        # docker-py 2.0 and newer
        pool_args = salt.utils.args.get_function_argspec(
            docker.types.IPAMPool.__init__).args
        create_pool = docker.types.IPAMPool
        create_config = docker.types.IPAMConfig
    except AttributeError:
        # docker-py < 2.0
        pool_args = salt.utils.args.get_function_argspec(
            docker.utils.create_ipam_pool).args
        create_pool = docker.utils.create_ipam_pool
        create_config = docker.utils.create_ipam_config

    for primary_key, alias_key in (('driver', 'ipam_driver'),
                                   ('options', 'ipam_opts')):

        if alias_key in kwargs:
            alias_val = kwargs.pop(alias_key)
            if primary_key in kwargs:
                log.warning(
                    'docker.create_ipam_config: Both \'%s\' and \'%s\' '
                    'passed. Ignoring \'%s\'',
                    alias_key, primary_key, alias_key
                )
            else:
                kwargs[primary_key] = alias_val

    if salt.utils.data.is_dictlist(kwargs.get('options')):
        kwargs['options'] = salt.utils.data.repack_dictlist(kwargs['options'])

    # Get all of the IPAM pool args that were passed as individual kwargs
    # instead of in the *pools tuple
    pool_kwargs = {}
    for key in list(kwargs):
        if key in pool_args:
            pool_kwargs[key] = kwargs.pop(key)

    pool_configs = []
    if pool_kwargs:
        pool_configs.append(create_pool(**pool_kwargs))
    pool_configs.extend([create_pool(**pool) for pool in pools])

    if pool_configs:
        # Sanity check the IPAM pools. docker-py's type/function for creating
        # an IPAM pool will allow you to create a pool with a gateway, IP
        # range, or map of aux addresses, even when no subnet is passed.
        # However, attempting to use this IPAM pool when creating the network
        # will cause the Docker Engine to throw an error.
        if any('Subnet' not in pool for pool in pool_configs):
            raise SaltInvocationError('A subnet is required in each IPAM pool')
        else:
            kwargs['pool_configs'] = pool_configs

    ret = create_config(**kwargs)
    pool_dicts = ret.get('Config')
    if pool_dicts:
        # When you inspect a network with custom IPAM configuration, only
        # arguments which were explictly passed are reflected. By contrast,
        # docker-py will include keys for arguments which were not passed in
        # but set the value to None. Thus, for ease of comparison, the below
        # loop will remove all keys with a value of None from the generated
        # pool configs.
        for idx, _ in enumerate(pool_dicts):
            for key in list(pool_dicts[idx]):
                if pool_dicts[idx][key] is None:
                    del pool_dicts[idx][key]

    return ret