Queries and converts the virtual machine properties to the available format
    from the schema. If the objects attribute is True the config objects will
    have extra properties, like 'object' which will include the
    vim.vm.device.VirtualDevice, this is necessary for deletion and update
    actions.

    name
        Name of the virtual machine

    datacenter
        Datacenter's name where the virtual machine is available

    objects
        Indicates whether to return the vmware object properties
        (eg. object, key) or just the properties which can be set

    service_instance
        vCenter service instance for connection and configuration

def get_vm_config(name, datacenter=None, objects=True, service_instance=None):
    '''
    Queries and converts the virtual machine properties to the available format
    from the schema. If the objects attribute is True the config objects will
    have extra properties, like 'object' which will include the
    vim.vm.device.VirtualDevice, this is necessary for deletion and update
    actions.

    name
        Name of the virtual machine

    datacenter
        Datacenter's name where the virtual machine is available

    objects
        Indicates whether to return the vmware object properties
        (eg. object, key) or just the properties which can be set

    service_instance
        vCenter service instance for connection and configuration
    '''
    properties = ['config.hardware.device',
                  'config.hardware.numCPU',
                  'config.hardware.numCoresPerSocket',
                  'config.nestedHVEnabled',
                  'config.cpuHotAddEnabled',
                  'config.cpuHotRemoveEnabled',
                  'config.hardware.memoryMB',
                  'config.memoryReservationLockedToMax',
                  'config.memoryHotAddEnabled',
                  'config.version',
                  'config.guestId',
                  'config.extraConfig',
                  'name']
    virtual_machine = salt.utils.vmware.get_vm_by_property(
        service_instance, name, vm_properties=properties, datacenter=datacenter)
    parent_ref = salt.utils.vmware.get_datacenter(
        service_instance=service_instance, datacenter_name=datacenter)
    current_config = {'name': name}
    current_config['cpu'] = {
        'count': virtual_machine['config.hardware.numCPU'],
        'cores_per_socket': virtual_machine['config.hardware.numCoresPerSocket'],
        'nested': virtual_machine['config.nestedHVEnabled'],
        'hotadd': virtual_machine['config.cpuHotAddEnabled'],
        'hotremove': virtual_machine['config.cpuHotRemoveEnabled']}

    current_config['memory'] = {
        'size': virtual_machine['config.hardware.memoryMB'],
        'unit': 'MB',
        'reservation_max': virtual_machine['config.memoryReservationLockedToMax'],
        'hotadd': virtual_machine['config.memoryHotAddEnabled']}
    current_config['image'] = virtual_machine['config.guestId']
    current_config['version'] = virtual_machine['config.version']
    current_config['advanced_configs'] = {}
    for extra_conf in virtual_machine['config.extraConfig']:
        try:
            current_config['advanced_configs'][extra_conf.key] = \
                int(extra_conf.value)
        except ValueError:
            current_config['advanced_configs'][extra_conf.key] = \
                extra_conf.value

    current_config['disks'] = []
    current_config['scsi_devices'] = []
    current_config['interfaces'] = []
    current_config['serial_ports'] = []
    current_config['cd_drives'] = []
    current_config['sata_controllers'] = []

    for device in virtual_machine['config.hardware.device']:
        if isinstance(device, vim.vm.device.VirtualSCSIController):
            controller = {}
            controller['adapter'] = device.deviceInfo.label
            controller['bus_number'] = device.busNumber
            bus_sharing = device.sharedBus
            if bus_sharing == 'noSharing':
                controller['bus_sharing'] = 'no_sharing'
            elif bus_sharing == 'virtualSharing':
                controller['bus_sharing'] = 'virtual_sharing'
            elif bus_sharing == 'physicalSharing':
                controller['bus_sharing'] = 'physical_sharing'
            if isinstance(device, vim.vm.device.ParaVirtualSCSIController):
                controller['type'] = 'paravirtual'
            elif isinstance(device, vim.vm.device.VirtualBusLogicController):
                controller['type'] = 'buslogic'
            elif isinstance(device, vim.vm.device.VirtualLsiLogicController):
                controller['type'] = 'lsilogic'
            elif isinstance(device, vim.vm.device.VirtualLsiLogicSASController):
                controller['type'] = 'lsilogic_sas'
            if objects:
                # int list, stores the keys of the disks which are attached
                # to this controller
                controller['device'] = device.device
                controller['key'] = device.key
                controller['object'] = device
            current_config['scsi_devices'].append(controller)
        if isinstance(device, vim.vm.device.VirtualDisk):
            disk = {}
            disk['adapter'] = device.deviceInfo.label
            disk['size'] = device.capacityInKB
            disk['unit'] = 'KB'
            controller = _get_device_by_key(
                virtual_machine['config.hardware.device'],
                device.controllerKey)
            disk['controller'] = controller.deviceInfo.label
            disk['address'] = \
                str(controller.busNumber) + ':' + str(device.unitNumber)
            disk['datastore'] = salt.utils.vmware.get_managed_object_name(
                device.backing.datastore)
            disk['thin_provision'] = device.backing.thinProvisioned
            disk['eagerly_scrub'] = device.backing.eagerlyScrub
            if objects:
                disk['key'] = device.key
                disk['unit_number'] = device.unitNumber
                disk['bus_number'] = controller.busNumber
                disk['controller_key'] = device.controllerKey
                disk['object'] = device
            current_config['disks'].append(disk)
        if isinstance(device, vim.vm.device.VirtualEthernetCard):
            interface = {}
            interface['adapter'] = device.deviceInfo.label
            interface['adapter_type'] = \
                salt.utils.vmware.get_network_adapter_object_type(device)
            interface['connectable'] = \
                {'allow_guest_control': device.connectable.allowGuestControl,
                 'connected': device.connectable.connected,
                 'start_connected': device.connectable.startConnected}
            interface['mac'] = device.macAddress
            if isinstance(device.backing,
                          vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo):
                interface['switch_type'] = 'distributed'
                pg_key = device.backing.port.portgroupKey
                network_ref = salt.utils.vmware.get_mor_by_property(
                    service_instance,
                    vim.DistributedVirtualPortgroup,
                    pg_key,
                    property_name='key',
                    container_ref=parent_ref)
            elif isinstance(device.backing,
                            vim.vm.device.VirtualEthernetCard.NetworkBackingInfo):
                interface['switch_type'] = 'standard'
                network_ref = device.backing.network
            interface['name'] = \
                salt.utils.vmware.get_managed_object_name(network_ref)
            if objects:
                interface['key'] = device.key
                interface['object'] = device
            current_config['interfaces'].append(interface)
        if isinstance(device, vim.vm.device.VirtualCdrom):
            drive = {}
            drive['adapter'] = device.deviceInfo.label
            controller = _get_device_by_key(
                virtual_machine['config.hardware.device'],
                device.controllerKey)
            drive['controller'] = controller.deviceInfo.label
            if isinstance(device.backing,
                          vim.vm.device.VirtualCdrom.RemotePassthroughBackingInfo):
                drive['device_type'] = 'client_device'
                drive['client_device'] = {'mode': 'passthrough'}
            if isinstance(device.backing,
                          vim.vm.device.VirtualCdrom.RemoteAtapiBackingInfo):
                drive['device_type'] = 'client_device'
                drive['client_device'] = {'mode': 'atapi'}
            if isinstance(device.backing,
                          vim.vm.device.VirtualCdrom.IsoBackingInfo):
                drive['device_type'] = 'datastore_iso_file'
                drive['datastore_iso_file'] = {'path': device.backing.fileName}
            drive['connectable'] = \
                {'allow_guest_control': device.connectable.allowGuestControl,
                 'connected': device.connectable.connected,
                 'start_connected': device.connectable.startConnected}
            if objects:
                drive['key'] = device.key
                drive['controller_key'] = device.controllerKey
                drive['object'] = device
            current_config['cd_drives'].append(drive)
        if isinstance(device, vim.vm.device.VirtualSerialPort):
            port = {}
            port['adapter'] = device.deviceInfo.label
            if isinstance(device.backing,
                          vim.vm.device.VirtualSerialPort.URIBackingInfo):
                port['type'] = 'network'
                port['backing'] = \
                    {'uri': device.backing.proxyURI,
                     'direction': device.backing.direction,
                     'filename': device.backing.serviceURI}
            if isinstance(device.backing,
                          vim.vm.device.VirtualSerialPort.PipeBackingInfo):
                port['type'] = 'pipe'
            if isinstance(device.backing,
                          vim.vm.device.VirtualSerialPort.FileBackingInfo):
                port['type'] = 'file'
            if isinstance(device.backing,
                          vim.vm.device.VirtualSerialPort.DeviceBackingInfo):
                port['type'] = 'device'
            port['yield'] = device.yieldOnPoll
            port['connectable'] = \
                {'allow_guest_control': device.connectable.allowGuestControl,
                 'connected': device.connectable.connected,
                 'start_connected': device.connectable.startConnected}
            if objects:
                port['key'] = device.key
                port['object'] = device
            current_config['serial_ports'].append(port)
        if isinstance(device, vim.vm.device.VirtualSATAController):
            sata = {}
            sata['adapter'] = device.deviceInfo.label
            sata['bus_number'] = device.busNumber
            if objects:
                sata['device'] = device.device  # keys of the connected devices
                sata['key'] = device.key
                sata['object'] = device
            current_config['sata_controllers'].append(sata)

    return current_config