Repository: cobbler/cobbler

Issue:
Type validation errors when trying to add an item.
### Describe the bug
When trying to add an item such as a distro, image, or other item which has arguments requiring a type int or float, the type validation in the setter method throws an exception. This has been confirmed to be a problem with at least --ctime/--mtime, as well as --network-count on images. Other arguments may also exhibit this behaviour, but not all arguments are sensitive to having string types as their values. 

<!--- A clear and concise description of what the bug is. -->
The problem can be tracked back to the combination of asserting types in certain setter methods and the fact that the building of the options in `cli.py::_add_parser_option_from_field()` does not include the type information from the field definition in the call to add_option(). 

<!--- HINT: You can paste gist.github.com links for long logs or larger files -->
The error looks something like this:

```
# cobbler image add --name=memtest86 \
        --arch=i386 \
        --breed=unix \
        --comment='Memtest86+ v5.01 image' \
        --file=/boot/memtest86+-5.01 \
        --image-type=direct \
        --network-count=1 \
        --virt-auto-boot=1 \
        --virt-bridge=xenbr0 \
        --virt-cpus=1 \
        --virt-file-size=5 \
        --virt-disk-driver=raw \
        --virt-ram=512 \
        --virt-type=xenpv
exception on server: Field network_count of object image needs to be of type int.
```

### Steps to reproduce

1. Add an item while specifying --ctime or add an image and specify the --network-count
2. Witness the error
3.

### Expected behavior
The argument would be properly processed and the item added/edited.

<!--- A clear and concise description of what you expected to happen. -->

### Cobbler version

<!--- Paste output from `cobbler version` -->
````
Cobbler 3.3.3
  source: ?, ?
  build time: Tue Jun 14 00:00:00 2022
````

### Operating system

<!--- On which operating system do you use Cobbler? -->
````
Rocky Linux release 9.2 (Blue Onyx)
````

### Cobbler log

<!--- Paste (partial) output from `/var/log/cobbler/cobbler.log` -->
````
[Thread-58] 2023-06-15T13:05:37 - INFO | Exception occurred: <class 'TypeError'>
[Thread-58] 2023-06-15T13:05:37 - INFO | Exception value: Field network_count of object image needs to be of type int.
[Thread-58] 2023-06-15T13:05:37 - INFO | Exception Info:
  File "/usr/lib/python3.9/site-packages/cobbler/remote.py", line 3707, in _dispatch
    return method_handle(*params)

  File "/usr/lib/python3.9/site-packages/cobbler/remote.py", line 2075, in xapi_object_edit
    self.modify_item(object_type, handle, key, value, token)

  File "/usr/lib/python3.9/site-packages/cobbler/remote.py", line 1802, in modify_item
    setattr(obj, attribute, arg)

  File "/usr/lib/python3.9/site-packages/cobbler/items/image.py", line 334, in network_count
    raise TypeError("Field network_count of object image needs to be of type int.")

````

### Screenshots

<!--- If applicable, add screenshots to help explain your problem. -->

### Additional information

<!--- Add any other context about the problem here. -->
I will attempt to create a PR against the 3.3.x branch to have the add_option() call passed the type information so that the optparse module converts the value to the expected type. I have an extensive dump from my 2.8 configuration which I have been migrating to the 3.3 syntax which has exercised this issue repeatedly on nearly all of 100+ items (thanks to --ctime alone).


Discussion:

Resolving patch:
diff --git a/cobbler/cli.py b/cobbler/cli.py
--- a/cobbler/cli.py
+++ b/cobbler/cli.py
@@ -696,6 +696,9 @@ def _add_parser_option_from_field(parser, field, settings):
         raise Exception("field %s default value (%s) is not listed in choices (%s)" % (name, default, str(choices)))
     if tooltip != "":
         description += " (%s)" % tooltip
+    field_type = field[7]
+    if field_type != "int" and field_type != 'float':
+        field_type = "string"
 
     # generate option string
     option_string = "--%s" % name.replace("_", "-")
@@ -705,7 +708,7 @@ def _add_parser_option_from_field(parser, field, settings):
         description += " (valid options: %s)" % ",".join(choices)
         parser.add_option(option_string, dest=name, help=description, choices=choices)
     else:
-        parser.add_option(option_string, dest=name, help=description)
+        parser.add_option(option_string, dest=name, help=description, type=field_type)
 
 
 def add_options_from_fields(object_type, parser, fields, network_interface_fields, settings, object_action):


Test patch: