Updates the configuration of the virtual machine if the config differs

    vm_name
        Virtual Machine name to be updated

    cpu
        CPU configuration options

    memory
        Memory configuration options

    version
        Virtual machine container hardware version

    image
        Virtual machine guest OS version identifier
        VirtualMachineGuestOsIdentifier

    interfaces
        Network interfaces configuration options

    disks
        Disks configuration options

    scsi_devices
        SCSI devices configuration options

    serial_ports
        Serial ports configuration options

    datacenter
        Datacenter where the virtual machine is available

    datastore
        Datastore where the virtual machine config files are available

    cd_dvd_drives
        CD/DVD drives configuration options

    advanced_config
        Advanced config parameters to be set for the virtual machine

    service_instance
        vCenter service instance for connection and configuration

def update_vm(vm_name, cpu=None, memory=None, image=None, version=None,
              interfaces=None, disks=None, scsi_devices=None,
              serial_ports=None, datacenter=None, datastore=None,
              cd_dvd_drives=None, sata_controllers=None, advanced_configs=None,
              service_instance=None):
    '''
    Updates the configuration of the virtual machine if the config differs

    vm_name
        Virtual Machine name to be updated

    cpu
        CPU configuration options

    memory
        Memory configuration options

    version
        Virtual machine container hardware version

    image
        Virtual machine guest OS version identifier
        VirtualMachineGuestOsIdentifier

    interfaces
        Network interfaces configuration options

    disks
        Disks configuration options

    scsi_devices
        SCSI devices configuration options

    serial_ports
        Serial ports configuration options

    datacenter
        Datacenter where the virtual machine is available

    datastore
        Datastore where the virtual machine config files are available

    cd_dvd_drives
        CD/DVD drives configuration options

    advanced_config
        Advanced config parameters to be set for the virtual machine

    service_instance
        vCenter service instance for connection and configuration
    '''
    current_config = get_vm_config(vm_name,
                                   datacenter=datacenter,
                                   objects=True,
                                   service_instance=service_instance)
    diffs = compare_vm_configs({'name': vm_name,
                                'cpu': cpu,
                                'memory': memory,
                                'image': image,
                                'version': version,
                                'interfaces': interfaces,
                                'disks': disks,
                                'scsi_devices': scsi_devices,
                                'serial_ports': serial_ports,
                                'datacenter': datacenter,
                                'datastore': datastore,
                                'cd_drives': cd_dvd_drives,
                                'sata_controllers': sata_controllers,
                                'advanced_configs': advanced_configs},
                               current_config)
    config_spec = vim.vm.ConfigSpec()
    datacenter_ref = salt.utils.vmware.get_datacenter(service_instance,
                                                      datacenter)
    vm_ref = salt.utils.vmware.get_mor_by_property(service_instance,
                                                   vim.VirtualMachine,
                                                   vm_name,
                                                   property_name='name',
                                                   container_ref=datacenter_ref)

    difference_keys = diffs.keys()
    if 'cpu' in difference_keys:
        if diffs['cpu'].changed() != set():
            _apply_cpu_config(config_spec, diffs['cpu'].current_dict)
    if 'memory' in difference_keys:
        if diffs['memory'].changed() != set():
            _apply_memory_config(config_spec, diffs['memory'].current_dict)
    if 'advanced_configs' in difference_keys:
        _apply_advanced_config(config_spec,
                               diffs['advanced_configs'].new_values,
                               vm_ref.config.extraConfig)
    if 'version' in difference_keys:
        _apply_hardware_version(version, config_spec, 'edit')
    if 'image' in difference_keys:
        config_spec.guestId = image
    new_scsi_devices = []
    if 'scsi_devices' in difference_keys and 'disks' in current_config:
        scsi_changes = []
        scsi_changes.extend(
            _update_scsi_devices(diffs['scsi_devices'].intersect,
                                 current_config['disks']))
        for item in diffs['scsi_devices'].removed:
            scsi_changes.append(_delete_device(item['object']))
        new_scsi_devices = _create_scsi_devices(diffs['scsi_devices'].added)
        scsi_changes.extend(new_scsi_devices)
        config_spec.deviceChange.extend(scsi_changes)
    if 'disks' in difference_keys:
        disk_changes = []
        disk_changes.extend(_update_disks(diffs['disks'].intersect))
        for item in diffs['disks'].removed:
            disk_changes.append(_delete_device(item['object']))
        # We will need the existing and new controllers as well
        scsi_controllers = [dev['object']
                            for dev in current_config['scsi_devices']]
        scsi_controllers.extend([device_spec.device
                                 for device_spec in new_scsi_devices])
        disk_changes.extend(
            _create_disks(service_instance,
                          diffs['disks'].added,
                          scsi_controllers=scsi_controllers,
                          parent=datacenter_ref))
        config_spec.deviceChange.extend(disk_changes)
    if 'interfaces' in difference_keys:
        network_changes = []
        network_changes.extend(
            _update_network_adapters(diffs['interfaces'].intersect,
                                     datacenter_ref))
        for item in diffs['interfaces'].removed:
            network_changes.append(_delete_device(item['object']))
        (adapters, nics) = _create_network_adapters(diffs['interfaces'].added,
                                                    datacenter_ref)
        network_changes.extend(adapters)
        config_spec.deviceChange.extend(network_changes)
    if 'serial_ports' in difference_keys:
        serial_changes = []
        serial_changes.extend(
            _update_serial_ports(diffs['serial_ports'].intersect))
        for item in diffs['serial_ports'].removed:
            serial_changes.append(_delete_device(item['object']))
        serial_changes.extend(
            _create_serial_ports(diffs['serial_ports'].added))
        config_spec.deviceChange.extend(serial_changes)
    new_controllers = []
    if 'sata_controllers' in difference_keys:
        # SATA controllers don't have many properties, it does not make sense
        # to update them
        sata_specs = _create_sata_controllers(diffs['sata_controllers'].added)
        for item in diffs['sata_controllers'].removed:
            sata_specs.append(_delete_device(item['object']))
        new_controllers.extend(sata_specs)
        config_spec.deviceChange.extend(sata_specs)
    if 'cd_drives' in difference_keys:
        cd_changes = []
        controllers = [dev['object']
                       for dev in current_config['sata_controllers']]
        controllers.extend([device_spec.device
                            for device_spec in new_controllers])
        cd_changes.extend(_update_cd_drives(diffs['cd_drives'].intersect,
                                            controllers=controllers,
                                            parent=datacenter_ref))
        for item in diffs['cd_drives'].removed:
            cd_changes.append(_delete_device(item['object']))
        cd_changes.extend(_create_cd_drives(diffs['cd_drives'].added,
                                            controllers=controllers,
                                            parent_ref=datacenter_ref))
        config_spec.deviceChange.extend(cd_changes)

    if difference_keys:
        salt.utils.vmware.update_vm(vm_ref, config_spec)
    changes = {}
    for key, properties in six.iteritems(diffs):
        # We can't display object, although we will need them for delete
        # and update actions, we will need to delete these before we summarize
        # the changes for the users
        if isinstance(properties, salt.utils.listdiffer.ListDictDiffer):
            properties.remove_diff(diff_key='object', diff_list='intersect')
            properties.remove_diff(diff_key='key', diff_list='intersect')
            properties.remove_diff(diff_key='object', diff_list='removed')
            properties.remove_diff(diff_key='key', diff_list='removed')
        changes[key] = properties.diffs

    return changes