예제 #1
0
def set_defaults(custom_attr_dict, custom_attrs):
    default_custom_attrs = get_valid_attrs(custom_attr_dict, 'default', custom_attrs)
    if 'client_timeout' in default_custom_attrs:
        client_timeout = default_custom_attrs.pop('client_timeout', None)
    else:
        client_timeout = 300000

    if 'server_timeout' in default_custom_attrs:
        server_timeout = default_custom_attrs.pop('server_timeout', None)
    else:
        server_timeout = 300000

    if 'connect_timeout' in default_custom_attrs:
        connect_timeout = default_custom_attrs.pop('connect_timeout', None)
    else:
        connect_timeout = 5000

    conf = [
        'defaults',
        'log global',
        'retries 3',
        'option redispatch',
        'timeout connect %d' % connect_timeout,
        'timeout client %d' % client_timeout,
        'timeout server %d' % server_timeout,
    ]

    # Adding custom_attributes config
    for key, value in default_custom_attrs.iteritems():
        cmd = custom_attr_dict['default'][key]['cmd']
        conf.append(cmd % value)

    res = "\n\t".join(conf)
    return res
def set_v1_frontend_backend(pool, custom_attr_dict, custom_attrs):
    conf = []
    vip = VirtualIpSM.get(pool.virtual_ip)
    if not vip and not vip.params["admin_state"]:
        return

    ssl = ""
    if vip.params["protocol"] == PROTO_HTTPS:
        ssl = "ssl crt haproxy_ssl_cert_path no-sslv3"

    lconf = [
        "frontend %s" % vip.uuid,
        "option tcplog",
        "bind %s:%s %s" % (vip.params["address"], vip.params["protocol_port"], ssl),
        "mode %s" % PROTO_MAP_V1[vip.params["protocol"]],
    ]
    if vip.params["protocol"] == PROTO_HTTP or vip.params["protocol"] == PROTO_HTTPS:
        lconf.append("option forwardfor")

    if pool and pool.params["admin_state"]:
        frontend_custom_attrs = get_valid_attrs(custom_attr_dict, "frontend", custom_attrs[pool.uuid])
        lconf.append("default_backend %s" % pool.uuid)
        # Adding custom_attributes config
        for key, value in frontend_custom_attrs.iteritems():
            cmd = custom_attr_dict["frontend"][key]["cmd"]
            lconf.append(cmd % value)
        res = "\n\t".join(lconf) + "\n\n"
        res += set_backend_v1(pool, custom_attr_dict, custom_attrs)
        conf.append(res)

    return "\n".join(conf)
예제 #3
0
def set_v1_frontend_backend(pool, custom_attr_dict, custom_attrs):
    conf = []
    vip = VirtualIpSM.get(pool.virtual_ip)
    if not vip and not vip.params['admin_state']:
        return

    ssl = ''
    if vip.params['protocol'] == PROTO_HTTPS:
        ssl = 'ssl crt haproxy_ssl_cert_path no-sslv3'

    lconf = [
        'frontend %s' % vip.uuid,
        'option tcplog',
        'bind %s:%s %s' % (vip.params['address'],
            vip.params['protocol_port'], ssl),
        'mode %s' % PROTO_MAP[vip.params['protocol']]
    ]
    if vip.params['protocol'] == PROTO_HTTP or \
            vip.params['protocol'] == PROTO_HTTPS:
        lconf.append('option forwardfor')

    frontend_custom_attrs = get_valid_attrs(custom_attr_dict, 'frontend', custom_attrs)
    if pool and pool.params['admin_state']:
        lconf.append('default_backend %s' % pool.uuid)
        # Adding custom_attributes config
        for key, value in frontend_custom_attrs.iteritems():
            cmd = custom_attr_dict['frontend'][key]['cmd']
            lconf.append(cmd % value)
        res = "\n\t".join(lconf) + '\n\n'
        res += set_backend(pool, custom_attr_dict, custom_attrs)
        conf.append(res)

    return "\n".join(conf)
예제 #4
0
def set_v1_frontend_backend(pool, custom_attr_dict, custom_attrs):
    conf = []
    vip = VirtualIpSM.get(pool.virtual_ip)
    if not vip or not vip.params['admin_state']:
        return "\n"

    ssl = ''
    if vip.params['protocol'] == PROTO_HTTPS:
        ssl = 'ssl crt haproxy_ssl_cert_path no-sslv3'

    lconf = [
        'frontend %s' % vip.uuid,
        'option tcplog',
        'bind %s:%s %s' % (vip.params['address'],
            vip.params['protocol_port'], ssl),
        'mode %s' % PROTO_MAP_V1[vip.params['protocol']]
    ]
    if vip.params['protocol'] == PROTO_HTTP or \
            vip.params['protocol'] == PROTO_HTTPS:
        lconf.append('option forwardfor')

    if pool and pool.params['admin_state']:
        frontend_custom_attrs = get_valid_attrs(custom_attr_dict, 'frontend',
                                                custom_attrs[pool.uuid])
        lconf.append('default_backend %s' % pool.uuid)
        # Adding custom_attributes config
        for key, value in frontend_custom_attrs.iteritems():
            cmd = custom_attr_dict['frontend'][key]['cmd']
            lconf.append(cmd % value)
        res = "\n\t".join(lconf) + '\n\n'
        res += set_backend_v1(pool, custom_attr_dict, custom_attrs)
        conf.append(res)

    return "\n".join(conf)
def set_globals(sock_path, custom_attr_dict, custom_attrs):
    global_custom_attrs = get_valid_attrs(custom_attr_dict, 'global',
                                          custom_attrs)
    if 'max_conn' in global_custom_attrs:
        maxconn = global_custom_attrs.pop('max_conn', None)
    else:
        maxconn = 65000

    if 'ssl_ciphers' in global_custom_attrs:
        ssl_ciphers = global_custom_attrs.pop('ssl_ciphers', None)
    else:
        ssl_ciphers = \
            'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:' \
            'ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:' \
            'RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS'

    conf = [
        'global', 'daemon', 'user nobody', 'group nogroup',
        'log /dev/log local0', 'log /dev/log local1 notice',
        'tune.ssl.default-dh-param 2048',
        'ssl-default-bind-ciphers %s' % ssl_ciphers, 'ulimit-n 200000',
        'maxconn %d' % maxconn
    ]
    conf.append('stats socket %s mode 0666 level user' % sock_path)

    # Adding custom_attributes config
    for key, value in global_custom_attrs.iteritems():
        cmd = custom_attr_dict['global'][key]['cmd']
        conf.append(cmd % value)

    res = "\n\t".join(conf)
    return res
def set_defaults(custom_attr_dict, custom_attrs):
    default_custom_attrs = get_valid_attrs(custom_attr_dict, 'default',
                                           custom_attrs)
    if 'client_timeout' in default_custom_attrs:
        client_timeout = default_custom_attrs.pop('client_timeout', None)
    else:
        client_timeout = 300000

    if 'server_timeout' in default_custom_attrs:
        server_timeout = default_custom_attrs.pop('server_timeout', None)
    else:
        server_timeout = 300000

    if 'connect_timeout' in default_custom_attrs:
        connect_timeout = default_custom_attrs.pop('connect_timeout', None)
    else:
        connect_timeout = 5000

    conf = [
        'defaults',
        'log global',
        'retries 3',
        'option redispatch',
        'timeout connect %d' % connect_timeout,
        'timeout client %d' % client_timeout,
        'timeout server %d' % server_timeout,
    ]

    # Adding custom_attributes config
    for key, value in default_custom_attrs.iteritems():
        cmd = custom_attr_dict['default'][key]['cmd']
        conf.append(cmd % value)

    res = "\n\t".join(conf)
    return res
예제 #7
0
def set_v2_frontend_backend(lb, custom_attr_dict, custom_attrs):
    conf = []
    for ll_id in lb.loadbalancer_listeners:
        ll = LoadbalancerListenerSM.get(ll_id)
        if not ll:
            continue
        if not ll.params['admin_state']:
            continue

        ssl = 'ssl'
        tls_sni_presence = False
        if ll.params['protocol'] == PROTO_TERMINATED_HTTPS:
            if ll.params['default_tls_container']:
                ssl += ' crt %s' % ll.params['default_tls_container']
                tls_sni_presence = True
            for sni_container in ll.params['sni_containers']:
                ssl += ' crt %s' % sni_container
                tls_sni_presence = True
        if (tls_sni_presence == False):
            ssl = ''
        else:
            ssl += ' no-sslv3'

        lconf = [
            'frontend %s' % ll.uuid,
            'option tcplog',
            'bind %s:%s %s' % (lb.params['vip_address'],
                ll.params['protocol_port'], ssl),
            'mode %s' % PROTO_MAP_V2[ll.params['protocol']],
        ]

        if 'connection_limit' in ll.params and ll.params['connection_limit'] > 0:
            lconf.append('maxconn %d' % ll.params['connection_limit'])

        if ll.params['protocol'] == PROTO_HTTP:
            lconf.append('option forwardfor')

        pool =  LoadbalancerPoolSM.get(ll.loadbalancer_pool)
        if pool and pool.params['admin_state']:
            frontend_custom_attrs = get_valid_attrs(custom_attr_dict,
                                                    'frontend',
                                                    custom_attrs[pool.uuid])
            lconf.append('default_backend %s' % pool.uuid)
            # Adding custom_attributes config
            for key, value in frontend_custom_attrs.iteritems():
                cmd = custom_attr_dict['frontend'][key]['cmd']
                lconf.append(cmd % value) 
            res = "\n\t".join(lconf) + '\n\n'
            res += set_backend_v2(pool, custom_attr_dict, custom_attrs)
            conf.append(res)

    return "\n".join(conf)
예제 #8
0
def set_globals(uuid, custom_attr_dict, custom_attrs):
    agg_custom_attrs = {}
    for key, value in custom_attrs.iteritems():
        agg_custom_attrs.update(custom_attrs[key])

    global_custom_attrs = get_valid_attrs(custom_attr_dict, 'global',
                                          agg_custom_attrs)
    if 'max_conn' in global_custom_attrs:
        maxconn = global_custom_attrs.pop('max_conn', None)
    else:
        maxconn = 65000

    if 'ssl_ciphers' in global_custom_attrs:
        ssl_ciphers = global_custom_attrs.pop('ssl_ciphers', None)
    else:
        ssl_ciphers = \
            'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:' \
            'ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:' \
            'RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS'

    logger_socket = '/var/log/contrail/lbaas/haproxy.log.sock'

    conf = [
        'global',
        'daemon',
        'user haproxy',
        'group haproxy',
        'log %s local0' % logger_socket,
        'log %s local1 notice' % logger_socket,
        'tune.ssl.default-dh-param 2048',
        'ssl-default-bind-ciphers %s' % ssl_ciphers,
        'ulimit-n 200000',
        'maxconn %d' % maxconn
    ]

    sock_path = '/var/lib/contrail/loadbalancer/haproxy/'
    sock_path += uuid + '/haproxy.sock'
    conf.append('stats socket %s mode 0666 level user' % sock_path)

    # Adding custom_attributes config
    for key, value in global_custom_attrs.iteritems():
        cmd = custom_attr_dict['global'][key]['cmd']
        conf.append(cmd % value)

    res = "\n\t".join(conf)
    return res
def set_v2_frontend_backend(lb, custom_attr_dict, custom_attrs):
    conf = []
    for ll_id in lb.loadbalancer_listeners:
        ll = LoadbalancerListenerSM.get(ll_id)
        if not ll:
            continue
        if not ll.params["admin_state"]:
            continue

        ssl = "ssl"
        tls_sni_presence = False
        if ll.params["protocol"] == PROTO_TERMINATED_HTTPS:
            if ll.params["default_tls_container"]:
                ssl += " crt %s" % ll.params["default_tls_container"]
                tls_sni_presence = True
            for sni_container in ll.params["sni_containers"]:
                ssl += " crt %s" % sni_container
                tls_sni_presence = True
        if tls_sni_presence == False:
            ssl = ""
        else:
            ssl += " no-sslv3"

        lconf = [
            "frontend %s" % ll.uuid,
            "option tcplog",
            "bind %s:%s %s" % (lb.params["vip_address"], ll.params["protocol_port"], ssl),
            "mode %s" % PROTO_MAP_V2[ll.params["protocol"]],
        ]
        if ll.params["protocol"] == PROTO_HTTP:
            lconf.append("option forwardfor")

        pool = LoadbalancerPoolSM.get(ll.loadbalancer_pool)
        if pool and pool.params["admin_state"]:
            frontend_custom_attrs = get_valid_attrs(custom_attr_dict, "frontend", custom_attrs[pool.uuid])
            lconf.append("default_backend %s" % pool.uuid)
            # Adding custom_attributes config
            for key, value in frontend_custom_attrs.iteritems():
                cmd = custom_attr_dict["frontend"][key]["cmd"]
                lconf.append(cmd % value)
            res = "\n\t".join(lconf) + "\n\n"
            res += set_backend_v2(pool, custom_attr_dict, custom_attrs)
            conf.append(res)

    return "\n".join(conf)
def set_globals(sock_path, custom_attr_dict, custom_attrs):
    agg_custom_attrs = {}
    for key, value in custom_attrs.iteritems():
        agg_custom_attrs.update(custom_attrs[key])

    global_custom_attrs = get_valid_attrs(custom_attr_dict, "global", agg_custom_attrs)
    if "max_conn" in global_custom_attrs:
        maxconn = global_custom_attrs.pop("max_conn", None)
    else:
        maxconn = 65000

    if "ssl_ciphers" in global_custom_attrs:
        ssl_ciphers = global_custom_attrs.pop("ssl_ciphers", None)
    else:
        ssl_ciphers = (
            "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:"
            "ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:"
            "RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS"
        )

    conf = [
        "global",
        "daemon",
        "user nobody",
        "group nogroup",
        "log /dev/log local0",
        "log /dev/log local1 notice",
        "tune.ssl.default-dh-param 2048",
        "ssl-default-bind-ciphers %s" % ssl_ciphers,
        "ulimit-n 200000",
        "maxconn %d" % maxconn,
    ]
    conf.append("stats socket %s mode 0666 level user" % sock_path)

    # Adding custom_attributes config
    for key, value in global_custom_attrs.iteritems():
        cmd = custom_attr_dict["global"][key]["cmd"]
        conf.append(cmd % value)

    res = "\n\t".join(conf)
    return res
def set_globals(sock_path, custom_attr_dict, custom_attrs):
    agg_custom_attrs = {}
    for key, value in custom_attrs.iteritems():
        agg_custom_attrs.update(custom_attrs[key])

    global_custom_attrs = get_valid_attrs(custom_attr_dict, 'global',
                                          agg_custom_attrs)
    if 'max_conn' in global_custom_attrs:
        maxconn = global_custom_attrs.pop('max_conn', None)
    else:
        maxconn = 65000

    if 'ssl_ciphers' in global_custom_attrs:
        ssl_ciphers = global_custom_attrs.pop('ssl_ciphers', None)
    else:
        ssl_ciphers = \
            'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:' \
            'ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:' \
            'RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS'

    conf = [
        'global',
        'daemon',
        'user nobody',
        'group nogroup',
        'log /dev/log local0',
        'log /dev/log local1 notice',
        'tune.ssl.default-dh-param 2048',
        'ssl-default-bind-ciphers %s' % ssl_ciphers,
        'ulimit-n 200000',
        'maxconn %d' % maxconn
    ]
    conf.append('stats socket %s mode 0666 level user' % sock_path)

    # Adding custom_attributes config
    for key, value in global_custom_attrs.iteritems():
        cmd = custom_attr_dict['global'][key]['cmd']
        conf.append(cmd % value)

    res = "\n\t".join(conf)
    return res
예제 #12
0
def set_backend_v2(pool, custom_attr_dict, custom_attrs):
    backend_custom_attrs = get_valid_attrs(custom_attr_dict, 'backend',
                                           custom_attrs[pool.uuid])
    conf = [
        'backend %s' % pool.uuid,
        'mode %s' % PROTO_MAP_V2[pool.params['protocol']],
        'balance %s' % LB_METHOD_MAP[pool.params['loadbalancer_method']]
    ]
    if pool.params['protocol'] == PROTO_HTTP:
        conf.append('option forwardfor')

    server_suffix = ''
    for hm_id in pool.loadbalancer_healthmonitors:
        hm = HealthMonitorSM.get(hm_id)
        if not hm:
            continue
        server_suffix, monitor_conf = set_health_monitor(hm)
        conf.extend(monitor_conf)

    session_conf = set_session_persistence(pool)
    conf.extend(session_conf)

    for member_id in pool.members:
        member = LoadbalancerMemberSM.get(member_id)
        if not member or \
            'admin_state' not in member.params or \
                not member.params['admin_state']:
            continue
        server = (('server %s %s:%s weight %s') %
                  (member.uuid, member.params['address'],
                   member.params['protocol_port'],
                   member.params['weight'])) + server_suffix
        conf.append(server)

    # Adding custom_attributes config
    for key, value in backend_custom_attrs.iteritems():
        cmd = custom_attr_dict['backend'][key]['cmd']
        conf.append(cmd % value)

    return "\n\t".join(conf) + "\n\n"
예제 #13
0
def set_backend_v2(pool, custom_attr_dict, custom_attrs):
    backend_custom_attrs = get_valid_attrs(custom_attr_dict, 'backend',
                                           custom_attrs[pool.uuid])
    conf = [
        'backend %s' % pool.uuid,
        'mode %s' % PROTO_MAP_V2[pool.params['protocol']],
        'balance %s' % LB_METHOD_MAP[pool.params['loadbalancer_method']]
    ]
    if pool.params['protocol'] == PROTO_HTTP:
        conf.append('option forwardfor')

    server_suffix = ''
    for hm_id in pool.loadbalancer_healthmonitors:
        hm = HealthMonitorSM.get(hm_id)
        if not hm:
            continue
        server_suffix, monitor_conf = set_health_monitor(hm)
        conf.extend(monitor_conf)

    session_conf = set_session_persistence(pool)
    conf.extend(session_conf)

    for member_id in pool.members:
        member = LoadbalancerMemberSM.get(member_id)
        if not member or \
            'admin_state' not in member.params or \
                not member.params['admin_state']:
            continue
        server = (('server %s %s:%s weight %s') % (member.uuid,
                  member.params['address'], member.params['protocol_port'],
                  member.params['weight'])) + server_suffix
        conf.append(server)

    # Adding custom_attributes config
    for key, value in backend_custom_attrs.iteritems():
        cmd = custom_attr_dict['backend'][key]['cmd']
        conf.append(cmd % value)

    return "\n\t".join(conf) + "\n\n"
def set_backend_v2(pool, custom_attr_dict, custom_attrs):
    backend_custom_attrs = get_valid_attrs(custom_attr_dict, "backend", custom_attrs[pool.uuid])
    conf = [
        "backend %s" % pool.uuid,
        "mode %s" % PROTO_MAP_V2[pool.params["protocol"]],
        "balance %s" % LB_METHOD_MAP[pool.params["loadbalancer_method"]],
    ]
    if pool.params["protocol"] == PROTO_HTTP:
        conf.append("option forwardfor")

    server_suffix = ""
    for hm_id in pool.loadbalancer_healthmonitors:
        hm = HealthMonitorSM.get(hm_id)
        if not hm:
            continue
        server_suffix, monitor_conf = set_health_monitor(hm)
        conf.extend(monitor_conf)

    session_conf = set_session_persistence(pool)
    conf.extend(session_conf)

    for member_id in pool.members:
        member = LoadbalancerMemberSM.get(member_id)
        if not member or not member.params["admin_state"]:
            continue
        server = (
            ("server %s %s:%s weight %s")
            % (member.uuid, member.params["address"], member.params["protocol_port"], member.params["weight"])
        ) + server_suffix
        conf.append(server)

    # Adding custom_attributes config
    for key, value in backend_custom_attrs.iteritems():
        cmd = custom_attr_dict["backend"][key]["cmd"]
        conf.append(cmd % value)

    return "\n\t".join(conf) + "\n"
def set_defaults(custom_attr_dict, custom_attrs):
    agg_custom_attrs = {}
    for key, value in custom_attrs.iteritems():
        agg_custom_attrs.update(custom_attrs[key])
    default_custom_attrs = get_valid_attrs(custom_attr_dict, "default", agg_custom_attrs)
    if "client_timeout" in default_custom_attrs:
        client_timeout = default_custom_attrs.pop("client_timeout", None)
    else:
        client_timeout = 300000

    if "server_timeout" in default_custom_attrs:
        server_timeout = default_custom_attrs.pop("server_timeout", None)
    else:
        server_timeout = 300000

    if "connect_timeout" in default_custom_attrs:
        connect_timeout = default_custom_attrs.pop("connect_timeout", None)
    else:
        connect_timeout = 5000

    conf = [
        "defaults",
        "log global",
        "retries 3",
        "option redispatch",
        "timeout connect %d" % connect_timeout,
        "timeout client %d" % client_timeout,
        "timeout server %d" % server_timeout,
    ]

    # Adding custom_attributes config
    for key, value in default_custom_attrs.iteritems():
        cmd = custom_attr_dict["default"][key]["cmd"]
        conf.append(cmd % value)

    res = "\n\t".join(conf)
    return res
예제 #16
0
def set_v2_frontend_backend(lb, custom_attr_dict, custom_attrs):
    conf = []
    lconf = ""
    pconf = ""

    listeners = get_listeners(lb)
    for listener in listeners:
        ll = listener['obj']
        sni_containers = listener['sni_containers']
        ssl = 'ssl'
        tls_sni_presence = False
        if ll.params['protocol'] == PROTO_TERMINATED_HTTPS:
            if ll.params['default_tls_container']:
                ssl += ' crt__%s' % ll.params['default_tls_container']
                tls_sni_presence = True
            for sni_container in sni_containers:
                ssl += ' crt__%s' % sni_container
                tls_sni_presence = True
        if (tls_sni_presence == False):
            ssl = ''
        else:
            ssl += ' no-sslv3'

        conf = [
            'frontend %s' % ll.uuid,
            'option tcplog',
            'bind %s:%s %s' % (lb.params['vip_address'],
                ll.params['protocol_port'], ssl),
            'mode %s' % PROTO_MAP_V2[ll.params['protocol']],
        ]

        if 'connection_limit' in ll.params and ll.params['connection_limit'] > 0:
            conf.append('maxconn %d' % ll.params['connection_limit'])

        if ll.params['protocol'] == PROTO_HTTP:
            conf.append('option forwardfor')

        pools = listener['pools']
        for pool_id in pools or []:
            pool =  LoadbalancerPoolSM.get(pool_id)
            if pool and pool.params['admin_state']:
                frontend_custom_attrs = get_valid_attrs(custom_attr_dict,
                                                        'frontend',
                                                        custom_attrs[pool.uuid])
                annotations = pool.annotations
                acl = {}
                if annotations and 'key_value_pair' in annotations:
                    for kv in annotations['key_value_pair'] or []:
                        acl[kv['key']] = kv['value']
                    if 'type' not in acl or acl['type'] == 'default':
                        conf.append('default_backend %s' % pool.uuid)
                    else:
                        acl_cdn = ""
                        host_cdn = ""
                        path_cdn = ""
                        if 'host' in acl:
                            host_cdn = "%s_host" % pool.uuid
                            conf.append('acl %s hdr(host) -i %s' %(host_cdn, acl['host']))
                        if 'path' in acl:
                            path_cdn = "%s_path" % pool.uuid
                            conf.append('acl %s_path path %s' %(pool.uuid, acl['path']))
                        acl_cdn = host_cdn + " " + path_cdn
                        conf.append('use_backend %s if %s' %(pool.uuid, acl_cdn))
                else:
                    conf.append('default_backend %s' % pool.uuid)

                # Adding custom_attributes config
                for key, value in frontend_custom_attrs.iteritems():
                    cmd = custom_attr_dict['frontend'][key]['cmd']
                    conf.append(cmd % value)
                conf.append("\n")
                pconf += set_backend_v2(pool, custom_attr_dict, custom_attrs)
        lconf += "\n\t".join(conf)

    conf = []
    conf.append(lconf)
    conf.append(pconf)

    return "\n".join(conf)