Repository: cobbler/cobbler

Issue:
The management interface is not found in tftpgen
### Describe the bug

On a server with several network interfaces, I need to specify which network interface to use for network install.

The interface has management set to True. However, the boot file generated by tftpgen does not include the correct interface.


### Steps to reproduce

1. Create a system with a management interface and netboot enabled

```
root@cobblerlab:~# cobbler system add --name foo --interface eno4 --profile generic-debian-11 --mac-address 00:11:22:33:44:55 --management true --netboot 1
root@cobblerlab:~# cobbler system report --name foo
Name                           : foo
Automatic Installation Template : <<inherit>>
Automatic Installation Template Metadata : <<inherit>>
TFTP Boot Files                : <<inherit>>
Boot loaders                   : <<inherit>>
Comment                        : 
Enable iPXE?                   : <<inherit>>
Fetchable Files                : <<inherit>>
DHCP Filename Override         : <<inherit>>
Gateway                        : 
Hostname                       : 
Image                          : 
IPv6 Autoconfiguration         : False
IPv6 Default Device            : 
Kernel Options                 : <<inherit>>
Kernel Options (Post Install)  : <<inherit>>
Management Classes             : <<inherit>>
Management Parameters          : <<inherit>>
Name Servers                   : []
Name Servers Search Path       : []
Netboot Enabled                : True
Next Server (IPv4) Override    : <<inherit>>
Next Server (IPv6) Override    : <<inherit>>
Owners                         : <<inherit>>
Power Management Address       : 
Power Management ID            : 
Power Identity File            : 
Power Management Options       : 
Power Management Password      : 
Power Management Type          : 
Power Management Username      : 
Profile                        : generic-debian-11
Internal Proxy                 : <<inherit>>
Redhat Management Key          : <<inherit>>
Repos Enabled                  : False
Serial Baud Rate               : -1
Serial Device #                : -1
Server Override                : <<inherit>>
Status                         : 
Template Files                 : {}
Virt Auto Boot                 : <<inherit>>
Virt CPUs                      : <<inherit>>
Virt Disk Driver Type          : <<inherit>>
Virt File Size(GB)             : <<inherit>>
Virt Path                      : <<inherit>>
Virt PXE Boot                  : False
Virt RAM (MB)                  : <<inherit>>
Virt Type                      : <<inherit>>
Interface =====                : eno4
Bonding Opts                   : 
Bridge Opts                    : 
CNAMES                         : []
InfiniBand Connected Mode      : False
DHCP Tag                       : 
DNS Name                       : 
Per-Interface Gateway          : 
Master Interface               : 
Interface Type                 : NA
IP Address                     : 
IPv6 Address                   : 
IPv6 Default Gateway           : 
IPv6 MTU                       : 
IPv6 Prefix                    : 
IPv6 Secondaries               : []
IPv6 Static Routes             : []
MAC Address                    : 00:11:22:33:44:55
Management Interface           : True
MTU                            : 
Subnet Mask                    : 
Static                         : False
Static Routes                  : []
Virt Bridge                    : 
```

2. Check the boot file
```
root@cobblerlab:~# cat /srv/tftp/pxelinux.cfg/01-00-11-22-33-44-55 
timeout 1
prompt 0
default foo
ontimeout foo
LABEL foo
	MENU LABEL foo
	kernel /images/debian-11/linux
	append initrd=/images/debian-11/initrd.gz  auto-install/enable=true priority=critical netcfg/choose_interface=auto url=http://172.31.0.10/cblr/svc/op/autoinstall/system/foo hostname=foo domain=local.lan suite=
	ipappend 2
```

The `netcfg/choose_interface=eno4` is missing.

### Expected behavior

```
root@cobblerlab:~# cat /srv/tftp/pxelinux.cfg/01-00-11-22-33-44-55 
timeout 1
prompt 0
default foo
ontimeout foo
LABEL foo
	MENU LABEL foo
	kernel /images/debian-11/linux
	append initrd=/images/debian-11/initrd.gz  auto-install/enable=true priority=critical netcfg/choose_interface=auto url=http://172.31.0.10/cblr/svc/op/autoinstall/system/foo netcfg/choose_interface=eno4 hostname=foo domain=local.lan suite=
	ipappend 2
```

or even

```
root@cobblerlab:~# cat /srv/tftp/pxelinux.cfg/01-00-11-22-33-44-55 
timeout 1
prompt 0
default foo
ontimeout foo
LABEL foo
	MENU LABEL foo
	kernel /images/debian-11/linux
	append initrd=/images/debian-11/initrd.gz  auto-install/enable=true priority=critical url=http://172.31.0.10/cblr/svc/op/autoinstall/system/foo netcfg/choose_interface=eno4 hostname=foo domain=local.lan suite=
	ipappend 2
```

### Cobbler version

<!--- Paste output from `cobbler version` -->
````root@cobblerlab:~# cobbler version
Cobbler 3.3.2
  source: ?, ?
  build time: Thu Jun  9 20:46:00 2022
````
+ backport patches, see https://github.com/cobbler/cobbler/compare/v3.3.2...btravouillon:cobbler:b3.3.2+patches

### Operating system

Debian 11

### Cobbler log

n/a

### Screenshots

n/a

### Additional information

n/a


Discussion:

Resolving patch:
diff --git a/cobbler/items/system.py b/cobbler/items/system.py
--- a/cobbler/items/system.py
+++ b/cobbler/items/system.py
@@ -90,7 +90,7 @@ def to_dict(self, resolved: bool = False) -> dict:
                 new_key = key[1:].lower()
                 key_value = self.__dict__[key]
                 if isinstance(key_value, enum.Enum):
-                    result[new_key] = self.__dict__[key].name
+                    result[new_key] = self.__dict__[key].name.lower()
                 elif (
                     isinstance(key_value, str)
                     and key_value == enums.VALUE_INHERITED
diff --git a/cobbler/modules/managers/isc.py b/cobbler/modules/managers/isc.py
--- a/cobbler/modules/managers/isc.py
+++ b/cobbler/modules/managers/isc.py
@@ -105,14 +105,10 @@ def write_v4_config(self, template_file="/etc/cobbler/dhcp.template"):
                     else:
                         ignore_macs.append(mac)
 
-                    ip = system.interfaces[interface["interface_master"]]["ip_address"]
-                    netmask = system.interfaces[interface["interface_master"]][
-                        "netmask"
-                    ]
-                    dhcp_tag = system.interfaces[interface["interface_master"]][
-                        "dhcp_tag"
-                    ]
-                    host = system.interfaces[interface["interface_master"]]["dns_name"]
+                    ip = system.interfaces[interface["interface_master"]].ip_address
+                    netmask = system.interfaces[interface["interface_master"]].netmask
+                    dhcp_tag = system.interfaces[interface["interface_master"]].dhcp_tag
+                    host = system.interfaces[interface["interface_master"]].dns_name
 
                     if ip is None or ip == "":
                         for (interface_name, interface_object) in list(
@@ -287,13 +283,11 @@ def write_v6_config(self, template_file="/etc/cobbler/dhcp6.template"):
                     else:
                         ignore_macs.append(mac)
 
-                    ip_v6 = system.interfaces[interface["interface_master"]][
-                        "ipv6_address"
-                    ]
-                    dhcp_tag = system.interfaces[interface["interface_master"]][
-                        "dhcp_tag"
-                    ]
-                    host = system.interfaces[interface["interface_master"]]["dns_name"]
+                    ip_v6 = system.interfaces[
+                        interface["interface_master"]
+                    ].ipv6_address
+                    dhcp_tag = system.interfaces[interface["interface_master"]].dhcp_tag
+                    host = system.interfaces[interface["interface_master"]].dns_name
 
                     if not ip_v6:
                         for (interface_name, interface_object) in list(
diff --git a/cobbler/tftpgen.py b/cobbler/tftpgen.py
--- a/cobbler/tftpgen.py
+++ b/cobbler/tftpgen.py
@@ -958,10 +958,10 @@ def build_kernel_options(
             # find the first management interface
             try:
                 for intf in list(system.interfaces.keys()):
-                    if system.interfaces[intf]["management"]:
+                    if system.interfaces[intf].management:
                         management_interface = intf
-                        if system.interfaces[intf]["mac_address"]:
-                            management_mac = system.interfaces[intf]["mac_address"]
+                        if system.interfaces[intf].mac_address:
+                            management_mac = system.interfaces[intf].mac_address
                         break
             except:
                 # just skip this then


Test patch:
diff --git a/tests/xmlrpcapi/non_object_calls_test.py b/tests/xmlrpcapi/non_object_calls_test.py
--- a/tests/xmlrpcapi/non_object_calls_test.py
+++ b/tests/xmlrpcapi/non_object_calls_test.py
@@ -212,7 +212,7 @@ def test_get_random_mac(remote, token):
                     "dns_name": "",
                     "if_gateway": "",
                     "interface_master": "",
-                    "interface_type": "NA",
+                    "interface_type": "na",
                     "ip_address": "",
                     "ipv6_address": "",
                     "ipv6_default_gateway": "",