Exemplo n.º 1
0
def _get_dracut_ipv4_argument(connection, iface, hostname):
    """Get dracut ip IPv4 configuration for given interface and NM connection.

    :param connection: NetworkManager connection
    :type connection: NM.RemoteConnection
    :param iface: network interface to be used
    :type iface: str
    :param hostname: static hostname to be configured
    :type hostname: str
    :returns: dracut ip argument or "" if the configuration can't be find
    :rtype: str
    """
    argument = ""
    ip4_config = connection.get_setting_ip4_config()
    ip4_method = ip4_config.get_method()
    if ip4_method == NM.SETTING_IP4_CONFIG_METHOD_AUTO:
        argument = "ip={}:dhcp".format(iface)
    elif ip4_method == NM.SETTING_IP4_CONFIG_METHOD_MANUAL:
        if ip4_config.get_num_addresses() > 0:
            addr = ip4_config.get_address(0)
            ip = addr.get_address()
            netmask = prefix2netmask(addr.get_prefix())
            gateway = ip4_config.get_gateway() or ""
            argument = "ip={}::{}:{}:{}:{}:none".format(
                ip, gateway, netmask, hostname, iface)
    return argument
Exemplo n.º 2
0
def get_kickstart_network_data(ifcfg,
                               nm_client,
                               network_data_class,
                               root_path=""):
    """Get kickstart data from ifcfg object.

    :param ifcfg: ifcfg file object
    :type ifcfg: IfcfgFile
    :param nm_client: instance of NetworkManager client
    :type nm_client: NM.Client
    :param network_data_class: pykickstart network command data class
    :type: pykickstart BaseData
    :param root_path: optional root path for ifcfg files to be updated
    :type root_path: str
    :returns: network_data object corresponding to the ifcfg object
    :rtype: network_data_class object instance
    """
    ifcfg.read()
    kwargs = {}

    # no network command for non-virtual device slaves
    if ifcfg.get("TYPE") not in ("Bond",
                                 "Team") and ifcfg.get("DEVICETYPE") != "Team":
        if ifcfg.get("MASTER") or ifcfg.get("TEAM_MASTER") or ifcfg.get(
                "BRIDGE"):
            return None

    # no support for wireless
    if ifcfg.get("TYPE") == "Wireless":
        return None

    # ipv4 and ipv6
    if ifcfg.get("ONBOOT") and ifcfg.get("ONBOOT") == "no":
        kwargs["onboot"] = False
    if ifcfg.get('MTU') and ifcfg.get('MTU') != "0":
        kwargs["mtu"] = ifcfg.get('MTU')
    # ipv4
    if not ifcfg.get('BOOTPROTO'):
        kwargs["noipv4"] = True
    else:
        if util.lowerASCII(ifcfg.get('BOOTPROTO')) == 'dhcp':
            kwargs["bootProto"] = "dhcp"
            if ifcfg.get('DHCPCLASS'):
                kwargs["dhcpclass"] = ifcfg.get('DHCPCLASS')
        elif ifcfg.get('IPADDR'):
            kwargs["bootProto"] = "static"
            kwargs["ip"] = ifcfg.get('IPADDR')
            netmask = ifcfg.get('NETMASK')
            prefix = ifcfg.get('PREFIX')
            if not netmask and prefix:
                netmask = prefix2netmask(int(prefix))
            if netmask:
                kwargs["netmask"] = netmask
            # note that --gateway is common for ipv4 and ipv6
            if ifcfg.get('GATEWAY'):
                kwargs["gateway"] = ifcfg.get('GATEWAY')
        elif ifcfg.get('IPADDR0'):
            kwargs["bootProto"] = "static"
            kwargs["ip"] = ifcfg.get('IPADDR0')
            prefix = ifcfg.get('PREFIX0')
            if prefix:
                netmask = prefix2netmask(int(prefix))
                kwargs["netmask"] = netmask
            # note that --gateway is common for ipv4 and ipv6
            if ifcfg.get('GATEWAY0'):
                kwargs["gateway"] = ifcfg.get('GATEWAY0')

    # ipv6
    if not ifcfg.get('IPV6INIT') or ifcfg.get('IPV6INIT') == "no":
        kwargs["noipv6"] = True
    else:
        if ifcfg.get('IPV6_AUTOCONF') in ("yes", ""):
            kwargs["ipv6"] = "auto"
        else:
            if ifcfg.get('IPV6ADDR'):
                kwargs["ipv6"] = ifcfg.get('IPV6ADDR')
                if ifcfg.get('IPV6_DEFAULTGW') \
                        and ifcfg.get('IPV6_DEFAULTGW') != "::":
                    kwargs["ipv6gateway"] = ifcfg.get('IPV6_DEFAULTGW')
            if ifcfg.get('DHCPV6C') == "yes":
                kwargs["ipv6"] = "dhcp"

    # ipv4 and ipv6
    dnsline = ''
    for key in ifcfg.info.keys():
        if util.upperASCII(key).startswith('DNS'):
            if dnsline == '':
                dnsline = ifcfg.get(key)
            else:
                dnsline += "," + ifcfg.get(key)
    if dnsline:
        kwargs["nameserver"] = dnsline

    if ifcfg.get("ETHTOOL_OPTS"):
        kwargs["ethtool"] = ifcfg.get("ETHTOOL_OPTS")

    if ifcfg.get("ESSID"):
        kwargs["essid"] = ifcfg.get("ESSID")

    # hostname
    if ifcfg.get("DHCP_HOSTNAME"):
        kwargs["hostname"] = ifcfg.get("DHCP_HOSTNAME")

    iface = ifcfg.get("DEVICE")
    if not iface:
        hwaddr = ifcfg.get("HWADDR")
        if hwaddr:
            iface = get_iface_from_hwaddr(nm_client, hwaddr)
    if iface:
        kwargs["device"] = iface

    # bonding
    # FIXME: dracut has only BOND_OPTS
    if ifcfg.get("BONDING_MASTER") == "yes" or ifcfg.get("TYPE") == "Bond":
        slaves = sorted(
            get_slaves_from_ifcfgs(
                nm_client,
                "MASTER",
                [ifcfg.get("DEVICE"), ifcfg.get("UUID")],
                root_path=root_path))
        if slaves:
            kwargs["bondslaves"] = ",".join(iface for iface, uuid in slaves)
        bondopts = ifcfg.get("BONDING_OPTS")
        if bondopts:
            sep = ","
            if sep in bondopts:
                sep = ";"
            kwargs["bondopts"] = sep.join(bondopts.split())

    # vlan
    if ifcfg.get("VLAN") == "yes" or ifcfg.get("TYPE") == "Vlan":
        physdev = ifcfg.get("PHYSDEV")
        if len(physdev) == NM_CONNECTION_UUID_LENGTH:
            physdev = get_iface_from_connection(nm_client, physdev)
        kwargs["device"] = physdev
        kwargs["vlanid"] = ifcfg.get("VLAN_ID")
        interface_name = ifcfg.get("DEVICE")
        default_name = default_ks_vlan_interface_name(kwargs["device"],
                                                      kwargs["vlanid"])
        if interface_name and interface_name != default_name:
            kwargs["interfacename"] = interface_name

    # bridging
    if ifcfg.get("TYPE") == "Bridge":
        slaves = sorted(
            get_slaves_from_ifcfgs(
                nm_client,
                "BRIDGE",
                [ifcfg.get("DEVICE"), ifcfg.get("UUID")],
                root_path=root_path))
        if slaves:
            kwargs["bridgeslaves"] = ",".join(iface for iface, uuid in slaves)

        bridgeopts = ifcfg.get("BRIDGING_OPTS").replace('_', '-').split()
        if ifcfg.get("STP"):
            bridgeopts.append("%s=%s" % ("stp", ifcfg.get("STP")))
        if ifcfg.get("DELAY"):
            bridgeopts.append("%s=%s" % ("forward-delay", ifcfg.get("DELAY")))
        if bridgeopts:
            kwargs["bridgeopts"] = ",".join(bridgeopts)

    nd = network_data_class(**kwargs)

    # teaming
    if ifcfg.get("TYPE") == "Team" or ifcfg.get("DEVICETYPE") == "Team":
        slaves = sorted(
            get_slaves_from_ifcfgs(
                nm_client,
                "TEAM_MASTER",
                [ifcfg.get("DEVICE"), ifcfg.get("UUID")],
                root_path=root_path))
        for iface, uuid in slaves:
            team_port_cfg = get_team_port_config_from_connection(
                nm_client, uuid)
            nd.teamslaves.append((iface, team_port_cfg))
        teamconfig = get_team_config_from_connection(nm_client,
                                                     ifcfg.get("UUID"))
        if teamconfig:
            nd.teamconfig = teamconfig
    return nd
Exemplo n.º 3
0
def get_dracut_arguments_from_ifcfg(nm_client, ifcfg, iface, target_ip, hostname):
    """Get dracut arguments for the iface and iSCSI target.

    The dracut arguments would activate the iface in initramfs so that the
    iSCSI target can be attached (for example to mount root filesystem).

    :param nm_client: instance of NetworkManager client
    :type nm_client: NM.Client
    :param ifcfg: ifcfg file object
    :type ifcfg: IfcfgFile
    :param iface: network interface used to connect to the target
    :type iface: str
    :param target_ip: IP of the iSCSI target
    :type target_ip: str
    :param hostname: static hostname to be configured
    :type hostname: str
    :returns: dracut arguments
    :rtype: set(str)
    """
    netargs = set()

    if ifcfg.get('BOOTPROTO') == 'ibft':
        netargs.add("rd.iscsi.ibft")
    elif target_ip:
        if hostname is None:
            hostname = ""
        # if using ipv6
        if ':' in target_ip:
            if ifcfg.get('DHCPV6C') == "yes":
                # XXX combination with autoconf not yet clear,
                # support for dhcpv6 is not yet implemented in NM/ifcfg-rh
                netargs.add("ip=%s:dhcp6" % iface)
            elif ifcfg.get('IPV6_AUTOCONF') == "yes":
                netargs.add("ip=%s:auto6" % iface)
            elif ifcfg.get('IPV6ADDR'):
                ipaddr = "[%s]" % ifcfg.get('IPV6ADDR')
                if ifcfg.get('IPV6_DEFAULTGW'):
                    gateway = "[%s]" % ifcfg.get('IPV6_DEFAULTGW')
                else:
                    gateway = ""
                netargs.add("ip=%s::%s::%s:%s:none" % (ipaddr, gateway,
                            hostname, iface))
        else:
            if util.lowerASCII(ifcfg.get('bootproto')) == 'dhcp':
                netargs.add("ip=%s:dhcp" % iface)
            else:
                cfgidx = ''
                if ifcfg.get('IPADDR0'):
                    cfgidx = '0'
                if ifcfg.get('GATEWAY%s' % cfgidx):
                    gateway = ifcfg.get('GATEWAY%s' % cfgidx)
                else:
                    gateway = ""
                netmask = ifcfg.get('NETMASK%s' % cfgidx)
                prefix = ifcfg.get('PREFIX%s' % cfgidx)
                if not netmask and prefix:
                    netmask = prefix2netmask(int(prefix))
                ipaddr = ifcfg.get('IPADDR%s' % cfgidx)
                netargs.add("ip=%s::%s:%s:%s:%s:none" %
                            (ipaddr, gateway, netmask, hostname, iface))

        hwaddr = ifcfg.get("HWADDR")
        if hwaddr:
            netargs.add("ifname=%s:%s" % (iface, hwaddr.lower()))

        if ifcfg.get("TYPE") == "Team" or ifcfg.get("DEVICETYPE") == "Team":
            slaves = sorted(get_slaves_from_ifcfgs(nm_client, "TEAM_MASTER", [iface, ifcfg.get("UUID")]))
            netargs.add("team=%s:%s" % (iface,
                                        ",".join(s_iface for s_iface, _uuid in slaves)))

        if ifcfg.get("TYPE") == "Vlan":
            physdev_spec = ifcfg.get("PHYSDEV")
            physdev = None
            # physical device can be specified by connection uuid (eg from nm-c-e)
            if len(physdev_spec) == NM_CONNECTION_UUID_LENGTH:
                ifcfg = get_ifcfg_file([("UUID", physdev_spec)])
                if ifcfg:
                    # On s390 with net.ifnames=0 there is no DEVICE
                    physdev = ifcfg.get("DEVICE") or ifcfg.get("NAME")
            else:
                ifcfg = get_ifcfg_file_of_device(nm_client, physdev_spec)
                if ifcfg:
                    physdev = physdev_spec
            if physdev:
                netargs.add("vlan=%s:%s" % (iface, physdev))
            else:
                log.error("can't find ifcfg of parent of vlan device %s specified by %s",
                          iface, physdev_spec)
                return netargs

    # For vlan ifcfg now refers to the physical device file
    nettype = ifcfg.get("NETTYPE")
    subchannels = ifcfg.get("SUBCHANNELS")
    if is_s390() and nettype and subchannels:
        znet = "rd.znet=%s,%s" % (nettype, subchannels)
        options = ifcfg.get("OPTIONS").strip("'\"")
        if options:
            options = filter(lambda x: x != '', options.split(' '))
            znet += ",%s" % (','.join(options))
        netargs.add(znet)

    return netargs
Exemplo n.º 4
0
def get_dracut_arguments_from_ifcfg(nm_client, ifcfg, iface, target_ip, hostname):
    """Get dracut arguments for the iface and iSCSI target.

    The dracut arguments would activate the iface in initramfs so that the
    iSCSI target can be attached (for example to mount root filesystem).

    :param nm_client: instance of NetworkManager client
    :type nm_client: NM.Client
    :param ifcfg: ifcfg file object
    :type ifcfg: IfcfgFile
    :param iface: network interface used to connect to the target
    :type iface: str
    :param target_ip: IP of the iSCSI target
    :type target_ip: str
    :param hostname: static hostname to be configured
    :type hostname: str
    :returns: dracut arguments
    :rtype: set(str)
    """
    netargs = set()

    if ifcfg.get('BOOTPROTO') == 'ibft':
        netargs.add("rd.iscsi.ibft")
    elif target_ip:
        if hostname is None:
            hostname = ""
        # if using ipv6
        if ':' in target_ip:
            if ifcfg.get('DHCPV6C') == "yes":
                # XXX combination with autoconf not yet clear,
                # support for dhcpv6 is not yet implemented in NM/ifcfg-rh
                netargs.add("ip=%s:dhcp6" % iface)
            elif ifcfg.get('IPV6_AUTOCONF') == "yes":
                netargs.add("ip=%s:auto6" % iface)
            elif ifcfg.get('IPV6ADDR'):
                ipaddr = "[%s]" % ifcfg.get('IPV6ADDR')
                if ifcfg.get('IPV6_DEFAULTGW'):
                    gateway = "[%s]" % ifcfg.get('IPV6_DEFAULTGW')
                else:
                    gateway = ""
                netargs.add("ip=%s::%s::%s:%s:none" % (ipaddr, gateway,
                            hostname, iface))
        else:
            if util.lowerASCII(ifcfg.get('bootproto')) == 'dhcp':
                netargs.add("ip=%s:dhcp" % iface)
            else:
                cfgidx = ''
                if ifcfg.get('IPADDR0'):
                    cfgidx = '0'
                if ifcfg.get('GATEWAY%s' % cfgidx):
                    gateway = ifcfg.get('GATEWAY%s' % cfgidx)
                else:
                    gateway = ""
                netmask = ifcfg.get('NETMASK%s' % cfgidx)
                prefix = ifcfg.get('PREFIX%s' % cfgidx)
                if not netmask and prefix:
                    netmask = prefix2netmask(int(prefix))
                ipaddr = ifcfg.get('IPADDR%s' % cfgidx)
                netargs.add("ip=%s::%s:%s:%s:%s:none" %
                            (ipaddr, gateway, netmask, hostname, iface))

        hwaddr = ifcfg.get("HWADDR")
        if hwaddr:
            netargs.add("ifname=%s:%s" % (iface, hwaddr.lower()))

        if ifcfg.get("TYPE") == "Team" or ifcfg.get("DEVICETYPE") == "Team":
            slaves = get_slaves_from_ifcfgs(nm_client, "TEAM_MASTER", [iface, ifcfg.get("UUID")])
            netargs.add("team=%s:%s" % (iface,
                                        ",".join(s_iface for s_iface, _uuid in slaves)))

        if ifcfg.get("TYPE") == "Vlan":
            physdev_spec = ifcfg.get("PHYSDEV")
            physdev = None
            # physical device can be specified by connection uuid (eg from nm-c-e)
            if len(physdev_spec) == NM_CONNECTION_UUID_LENGTH:
                ifcfg = get_ifcfg_file([("UUID", physdev_spec)])
                if ifcfg:
                    # On s390 with net.ifnames=0 there is no DEVICE
                    physdev = ifcfg.get("DEVICE") or ifcfg.get("NAME")
            else:
                ifcfg = get_ifcfg_file_of_device(nm_client, physdev_spec)
                if ifcfg:
                    physdev = physdev_spec
            if physdev:
                netargs.add("vlan=%s:%s" % (iface, physdev))
            else:
                log.error("can't find ifcfg of parent of vlan device %s specified by %s",
                          iface, physdev_spec)
                return netargs

    # For vlan ifcfg now refers to the physical device file
    nettype = ifcfg.get("NETTYPE")
    subchannels = ifcfg.get("SUBCHANNELS")
    if is_s390() and nettype and subchannels:
        znet = "rd.znet=%s,%s" % (nettype, subchannels)
        options = ifcfg.get("OPTIONS").strip("'\"")
        if options:
            options = filter(lambda x: x != '', options.split(' '))
            znet += ",%s" % (','.join(options))
        netargs.add(znet)

    return netargs
Exemplo n.º 5
0
def get_kickstart_network_data(ifcfg, nm_client, network_data_class, root_path=""):
    """Get kickstart data from ifcfg object.

    :param ifcfg: ifcfg file object
    :type ifcfg: IfcfgFile
    :param nm_client: instance of NetworkManager client
    :type nm_client: NM.Client
    :param network_data_class: pykickstart network command data class
    :type: pykickstart BaseData
    :param root_path: optional root path for ifcfg files to be updated
    :type root_path: str
    :returns: network_data object corresponding to the ifcfg object
    :rtype: network_data_class object instance
    """
    ifcfg.read()
    kwargs = {}

    # no network command for non-virtual device slaves
    if ifcfg.get("TYPE") not in ("Bond", "Team") and ifcfg.get("DEVICETYPE") != "Team":
        if ifcfg.get("MASTER") or ifcfg.get("TEAM_MASTER") or ifcfg.get("BRIDGE"):
            return None

    # no support for wireless
    if ifcfg.get("TYPE") == "Wireless":
        return None

    # ipv4 and ipv6
    if ifcfg.get("ONBOOT") and ifcfg.get("ONBOOT") == "no":
        kwargs["onboot"] = False
    if ifcfg.get('MTU') and ifcfg.get('MTU') != "0":
        kwargs["mtu"] = ifcfg.get('MTU')
    # ipv4
    if not ifcfg.get('BOOTPROTO'):
        kwargs["noipv4"] = True
    else:
        if util.lowerASCII(ifcfg.get('BOOTPROTO')) == 'dhcp':
            kwargs["bootProto"] = "dhcp"
            if ifcfg.get('DHCPCLASS'):
                kwargs["dhcpclass"] = ifcfg.get('DHCPCLASS')
        elif ifcfg.get('IPADDR'):
            kwargs["bootProto"] = "static"
            kwargs["ip"] = ifcfg.get('IPADDR')
            netmask = ifcfg.get('NETMASK')
            prefix = ifcfg.get('PREFIX')
            if not netmask and prefix:
                netmask = prefix2netmask(int(prefix))
            if netmask:
                kwargs["netmask"] = netmask
            # note that --gateway is common for ipv4 and ipv6
            if ifcfg.get('GATEWAY'):
                kwargs["gateway"] = ifcfg.get('GATEWAY')
        elif ifcfg.get('IPADDR0'):
            kwargs["bootProto"] = "static"
            kwargs["ip"] = ifcfg.get('IPADDR0')
            prefix = ifcfg.get('PREFIX0')
            if prefix:
                netmask = prefix2netmask(int(prefix))
                kwargs["netmask"] = netmask
            # note that --gateway is common for ipv4 and ipv6
            if ifcfg.get('GATEWAY0'):
                kwargs["gateway"] = ifcfg.get('GATEWAY0')

    # ipv6
    if not ifcfg.get('IPV6INIT') or ifcfg.get('IPV6INIT') == "no":
        kwargs["noipv6"] = True
    else:
        if ifcfg.get('IPV6_AUTOCONF') in ("yes", ""):
            kwargs["ipv6"] = "auto"
        else:
            if ifcfg.get('IPV6ADDR'):
                kwargs["ipv6"] = ifcfg.get('IPV6ADDR')
                if ifcfg.get('IPV6_DEFAULTGW') \
                        and ifcfg.get('IPV6_DEFAULTGW') != "::":
                    kwargs["ipv6gateway"] = ifcfg.get('IPV6_DEFAULTGW')
            if ifcfg.get('DHCPV6C') == "yes":
                kwargs["ipv6"] = "dhcp"

    # ipv4 and ipv6
    dnsline = ''
    for key in ifcfg.info.keys():
        if util.upperASCII(key).startswith('DNS'):
            if dnsline == '':
                dnsline = ifcfg.get(key)
            else:
                dnsline += "," + ifcfg.get(key)
    if dnsline:
        kwargs["nameserver"] = dnsline

    if ifcfg.get("ETHTOOL_OPTS"):
        kwargs["ethtool"] = ifcfg.get("ETHTOOL_OPTS")

    if ifcfg.get("ESSID"):
        kwargs["essid"] = ifcfg.get("ESSID")

    # hostname
    if ifcfg.get("DHCP_HOSTNAME"):
        kwargs["hostname"] = ifcfg.get("DHCP_HOSTNAME")

    iface = ifcfg.get("DEVICE")
    if not iface:
        hwaddr = ifcfg.get("HWADDR")
        if hwaddr:
            iface = get_iface_from_hwaddr(nm_client, hwaddr)
    if iface:
        kwargs["device"] = iface

    # bonding
    # FIXME: dracut has only BOND_OPTS
    if ifcfg.get("BONDING_MASTER") == "yes" or ifcfg.get("TYPE") == "Bond":
        slaves = sorted(get_slaves_from_ifcfgs(nm_client,
                                               "MASTER",
                                               [ifcfg.get("DEVICE"), ifcfg.get("UUID")],
                                               root_path=root_path))
        if slaves:
            kwargs["bondslaves"] = ",".join(iface for iface, uuid in slaves)
        bondopts = ifcfg.get("BONDING_OPTS")
        if bondopts:
            sep = ","
            if sep in bondopts:
                sep = ";"
            kwargs["bondopts"] = sep.join(bondopts.split())

    # vlan
    if ifcfg.get("VLAN") == "yes" or ifcfg.get("TYPE") == "Vlan":
        physdev = ifcfg.get("PHYSDEV")
        if len(physdev) == NM_CONNECTION_UUID_LENGTH:
            physdev = get_iface_from_connection(nm_client, physdev)
        kwargs["device"] = physdev
        kwargs["vlanid"] = ifcfg.get("VLAN_ID")
        interface_name = ifcfg.get("DEVICE")
        if interface_name and interface_name != default_ks_vlan_interface_name(kwargs["device"], kwargs["vlanid"]):
            kwargs["interfacename"] = interface_name

    # bridging
    if ifcfg.get("TYPE") == "Bridge":
        slaves = sorted(get_slaves_from_ifcfgs(nm_client,
                                               "BRIDGE",
                                               [ifcfg.get("DEVICE"), ifcfg.get("UUID")],
                                               root_path=root_path))
        if slaves:
            kwargs["bridgeslaves"] = ",".join(iface for iface, uuid in slaves)

        bridgeopts = ifcfg.get("BRIDGING_OPTS").replace('_', '-').split()
        if ifcfg.get("STP"):
            bridgeopts.append("%s=%s" % ("stp", ifcfg.get("STP")))
        if ifcfg.get("DELAY"):
            bridgeopts.append("%s=%s" % ("forward-delay", ifcfg.get("DELAY")))
        if bridgeopts:
            kwargs["bridgeopts"] = ",".join(bridgeopts)

    nd = network_data_class(**kwargs)

    # teaming
    if ifcfg.get("TYPE") == "Team" or ifcfg.get("DEVICETYPE") == "Team":
        slaves = sorted(get_slaves_from_ifcfgs(nm_client,
                                               "TEAM_MASTER",
                                               [ifcfg.get("DEVICE"), ifcfg.get("UUID")],
                                               root_path=root_path))
        for iface, uuid in slaves:
            team_port_cfg = get_team_port_config_from_connection(nm_client, uuid)
            nd.teamslaves.append((iface, team_port_cfg))
        teamconfig = get_team_config_from_connection(nm_client, ifcfg.get("UUID"))
        if teamconfig:
            nd.teamconfig = teamconfig
    return nd