I actually had to work around this same issue when developing the prov utility we use internally at Wolfram. I'm not sure why Cobbler's data representation isn't bidirectional. I effectively do the following:
system_name = '(something)' # The name of the system.
system_data = {} # The desired final state of the system data here.
# Pull out the interfaces dictionary.
if 'interfaces' in system_data:
interfaces = system_data.pop('interfaces')
else:
interfaces = {}
# Apply the non-interfaces data.
cobbler_server.xapi_object_edit('systems', system_name, 'edit', system_data, self.token)
# Apply interface-specific data.
handle = cobbler_server.get_system_handle(system_name, self.token)
ninterfaces = {}
for iname, ival in interfaces.items():
for k, v in ival.items():
if k in ['dns_name', 'ip_address', 'mac_address']:
if v:
ninterfaces[k.replace('_', '') + '-' + iname] = v
else:
ninterfaces[k + '-' + iname] = v
cobbler_server.modify_system(
handle,
'modify_interface',
ninterfaces,
self.token
)
cobbler_server.save_system(handle, self.token)