Manage the SSH configuration for a host including whether or not SSH is running or
    the presence of a given SSH key. Note: Only one ssh key can be uploaded for root.
    Uploading a second key will replace any existing key.

    name
        Name of the state.

    service_running
        Ensures whether or not the SSH service should be running on a host. Represented
        as a boolean value where ``True`` indicates that SSH should be running and
        ``False`` indicates that SSH should stopped.

        In order to update SSH keys, the SSH service must be running.

    ssh_key
        Public SSH key to added to the authorized_keys file on the ESXi host. You can
        use ``ssh_key`` or ``ssh_key_file``, but not both.

    ssh_key_file
        File containing the public SSH key to be added to the authorized_keys file on
        the ESXi host. You can use ``ssh_key_file`` or ``ssh_key``, but not both.

    service_policy
        The policy to set for the NTP service.

        .. note::

            When setting the service policy to ``off`` or ``on``, you *must* quote the
            setting. If you don't, the yaml parser will set the string to a boolean,
            which will cause trouble checking for stateful changes and will error when
            trying to set the policy on the ESXi host.

    service_restart
        If set to ``True``, the SSH service will be restarted, regardless of its
        previous running state. Default is ``False``.

    certificate_verify
        If set to ``True``, the SSL connection must present a valid certificate.
        Default is ``False``.

    Example:

    .. code-block:: yaml

        configure-host-ssh:
          esxi.ssh_configured:
            - service_running: True
            - ssh_key_file: /etc/salt/ssh_keys/my_key.pub
            - service_policy: 'on'
            - service_restart: True
            - certificate_verify: True

def ssh_configured(name,
                   service_running,
                   ssh_key=None,
                   ssh_key_file=None,
                   service_policy=None,
                   service_restart=False,
                   certificate_verify=False):
    '''
    Manage the SSH configuration for a host including whether or not SSH is running or
    the presence of a given SSH key. Note: Only one ssh key can be uploaded for root.
    Uploading a second key will replace any existing key.

    name
        Name of the state.

    service_running
        Ensures whether or not the SSH service should be running on a host. Represented
        as a boolean value where ``True`` indicates that SSH should be running and
        ``False`` indicates that SSH should stopped.

        In order to update SSH keys, the SSH service must be running.

    ssh_key
        Public SSH key to added to the authorized_keys file on the ESXi host. You can
        use ``ssh_key`` or ``ssh_key_file``, but not both.

    ssh_key_file
        File containing the public SSH key to be added to the authorized_keys file on
        the ESXi host. You can use ``ssh_key_file`` or ``ssh_key``, but not both.

    service_policy
        The policy to set for the NTP service.

        .. note::

            When setting the service policy to ``off`` or ``on``, you *must* quote the
            setting. If you don't, the yaml parser will set the string to a boolean,
            which will cause trouble checking for stateful changes and will error when
            trying to set the policy on the ESXi host.

    service_restart
        If set to ``True``, the SSH service will be restarted, regardless of its
        previous running state. Default is ``False``.

    certificate_verify
        If set to ``True``, the SSL connection must present a valid certificate.
        Default is ``False``.

    Example:

    .. code-block:: yaml

        configure-host-ssh:
          esxi.ssh_configured:
            - service_running: True
            - ssh_key_file: /etc/salt/ssh_keys/my_key.pub
            - service_policy: 'on'
            - service_restart: True
            - certificate_verify: True

    '''
    ret = {'name': name,
           'result': False,
           'changes': {},
           'comment': ''}
    esxi_cmd = 'esxi.cmd'
    host = __pillar__['proxy']['host']
    ssh = 'ssh'

    ssh_running = __salt__[esxi_cmd]('get_service_running',
                                     service_name=ssh).get(host)
    error = ssh_running.get('Error')
    if error:
        ret['comment'] = 'Error: {0}'.format(error)
        return ret
    ssh_running = ssh_running.get(ssh)

    # Configure SSH service_running state, if changed.
    if service_running != ssh_running:
        # Only actually run the command if not using test=True
        if not __opts__['test']:
            # Start SSH if service_running=True
            if service_running is True:
                enable = __salt__[esxi_cmd]('service_start',
                                            service_name=ssh).get(host)
                error = enable.get('Error')
                if error:
                    ret['comment'] = 'Error: {0}'.format(error)
                    return ret
            # Disable SSH if service_running=False
            else:
                disable = __salt__[esxi_cmd]('service_stop',
                                             service_name=ssh).get(host)
                error = disable.get('Error')
                if error:
                    ret['comment'] = 'Error: {0}'.format(error)
                    return ret

        ret['changes'].update({'service_running':
                              {'old': ssh_running,
                               'new': service_running}})

    # If uploading an SSH key or SSH key file, see if there's a current
    # SSH key and compare the current key to the key set in the state.
    current_ssh_key, ssh_key_changed = None, False
    if ssh_key or ssh_key_file:
        current_ssh_key = __salt__[esxi_cmd]('get_ssh_key',
                                             certificate_verify=certificate_verify)
        error = current_ssh_key.get('Error')
        if error:
            ret['comment'] = 'Error: {0}'.format(error)
            return ret
        current_ssh_key = current_ssh_key.get('key')
        if current_ssh_key:
            clean_current_key = _strip_key(current_ssh_key).split(' ')
            if not ssh_key:
                ssh_key = ''
                # Open ssh key file and read in contents to create one key string
                with salt.utils.files.fopen(ssh_key_file, 'r') as key_file:
                    for line in key_file:
                        if line.startswith('#'):
                            # Commented line
                            continue
                        ssh_key = ssh_key + line

            clean_ssh_key = _strip_key(ssh_key).split(' ')
            # Check that the first two list items of clean key lists are equal.
            if clean_current_key[0] != clean_ssh_key[0] or clean_current_key[1] != clean_ssh_key[1]:
                ssh_key_changed = True
        else:
            # If current_ssh_key is None, but we're setting a new key with
            # either ssh_key or ssh_key_file, then we need to flag the change.
            ssh_key_changed = True

    # Upload SSH key, if changed.
    if ssh_key_changed:
        if not __opts__['test']:
            # Upload key
            response = __salt__[esxi_cmd]('upload_ssh_key',
                                          ssh_key=ssh_key,
                                          ssh_key_file=ssh_key_file,
                                          certificate_verify=certificate_verify)
            error = response.get('Error')
            if error:
                ret['comment'] = 'Error: {0}'.format(error)
                return ret
        ret['changes'].update({'SSH Key':
                              {'old': current_ssh_key,
                               'new': ssh_key if ssh_key else ssh_key_file}})

    # Configure service_policy
    if service_policy:
        current_service_policy = __salt__[esxi_cmd]('get_service_policy',
                                                    service_name=ssh).get(host)
        error = current_service_policy.get('Error')
        if error:
            ret['comment'] = 'Error: {0}'.format(error)
            return ret
        current_service_policy = current_service_policy.get(ssh)

        if service_policy != current_service_policy:
            # Only run the command if not using test=True
            if not __opts__['test']:
                response = __salt__[esxi_cmd]('set_service_policy',
                                              service_name=ssh,
                                              service_policy=service_policy).get(host)
                error = response.get('Error')
                if error:
                    ret['comment'] = 'Error: {0}'.format(error)
                    return ret
            ret['changes'].update({'service_policy':
                                  {'old': current_service_policy,
                                   'new': service_policy}})

    # Restart ssh_service if service_restart=True
    if service_restart:
        # Only run the command if not using test=True
        if not __opts__['test']:
            response = __salt__[esxi_cmd]('service_restart',
                                          service_name=ssh).get(host)
            error = response.get('Error')
            if error:
                ret['comment'] = 'Error: {0}'.format(error)
                return ret
        ret['changes'].update({'service_restart':
                              {'old': '',
                               'new': 'SSH service restarted.'}})

    ret['result'] = True
    if ret['changes'] == {}:
        ret['comment'] = 'SSH service is already in the desired state.'
        return ret

    if __opts__['test']:
        ret['result'] = None
        ret['comment'] = 'SSH service state will change.'

    return ret