Ensures the specified syslog configuration parameters. By default,
    this state will reset the syslog service after any new or changed
    parameters are set successfully.

    name
        Name of the state.

    syslog_configs
        Name of parameter to set (corresponds to the command line switch for
        esxcli without the double dashes (--))

        Valid syslog_config values are ``logdir``, ``loghost``, ``logdir-unique``,
        ``default-rotate``, ``default-size``, and ``default-timeout``.

        Each syslog_config option also needs a configuration value to set.
        For example, ``loghost`` requires URLs or IP addresses to use for
        logging. Multiple log servers can be specified by listing them,
        comma-separated, but without spaces before or after commas

        (reference: https://blogs.vmware.com/vsphere/2012/04/configuring-multiple-syslog-servers-for-esxi-5.html)

    firewall
        Enable the firewall rule set for syslog. Defaults to ``True``.

    reset_service
        After a successful parameter set, reset the service. Defaults to ``True``.

    reset_syslog_config
        Resets the syslog service to it's default settings. Defaults to ``False``.
        If set to ``True``, default settings defined by the list of syslog configs
        in ``reset_configs`` will be reset before running any other syslog settings.

    reset_configs
        A comma-delimited list of parameters to reset. Only runs if
        ``reset_syslog_config`` is set to ``True``. If ``reset_syslog_config`` is set
        to ``True``, but no syslog configs are listed in ``reset_configs``, then
        ``reset_configs`` will be set to ``all`` by default.

        See ``syslog_configs`` parameter above for a list of valid options.

    Example:

    .. code-block:: yaml

        configure-host-syslog:
          esxi.syslog_configured:
            - syslog_configs:
                loghost: ssl://localhost:5432,tcp://10.1.0.1:1514
                default-timeout: 120
            - firewall: True
            - reset_service: True
            - reset_syslog_config: True
            - reset_configs: loghost,default-timeout

def syslog_configured(name,
                      syslog_configs,
                      firewall=True,
                      reset_service=True,
                      reset_syslog_config=False,
                      reset_configs=None):
    '''
    Ensures the specified syslog configuration parameters. By default,
    this state will reset the syslog service after any new or changed
    parameters are set successfully.

    name
        Name of the state.

    syslog_configs
        Name of parameter to set (corresponds to the command line switch for
        esxcli without the double dashes (--))

        Valid syslog_config values are ``logdir``, ``loghost``, ``logdir-unique``,
        ``default-rotate``, ``default-size``, and ``default-timeout``.

        Each syslog_config option also needs a configuration value to set.
        For example, ``loghost`` requires URLs or IP addresses to use for
        logging. Multiple log servers can be specified by listing them,
        comma-separated, but without spaces before or after commas

        (reference: https://blogs.vmware.com/vsphere/2012/04/configuring-multiple-syslog-servers-for-esxi-5.html)

    firewall
        Enable the firewall rule set for syslog. Defaults to ``True``.

    reset_service
        After a successful parameter set, reset the service. Defaults to ``True``.

    reset_syslog_config
        Resets the syslog service to it's default settings. Defaults to ``False``.
        If set to ``True``, default settings defined by the list of syslog configs
        in ``reset_configs`` will be reset before running any other syslog settings.

    reset_configs
        A comma-delimited list of parameters to reset. Only runs if
        ``reset_syslog_config`` is set to ``True``. If ``reset_syslog_config`` is set
        to ``True``, but no syslog configs are listed in ``reset_configs``, then
        ``reset_configs`` will be set to ``all`` by default.

        See ``syslog_configs`` parameter above for a list of valid options.

    Example:

    .. code-block:: yaml

        configure-host-syslog:
          esxi.syslog_configured:
            - syslog_configs:
                loghost: ssl://localhost:5432,tcp://10.1.0.1:1514
                default-timeout: 120
            - firewall: True
            - reset_service: True
            - reset_syslog_config: True
            - reset_configs: loghost,default-timeout
    '''
    ret = {'name': name,
           'result': False,
           'changes': {},
           'comment': ''}
    esxi_cmd = 'esxi.cmd'
    host = __pillar__['proxy']['host']

    if reset_syslog_config:
        if not reset_configs:
            reset_configs = 'all'
        # Only run the command if not using test=True
        if not __opts__['test']:
            reset = __salt__[esxi_cmd]('reset_syslog_config',
                                       syslog_config=reset_configs).get(host)
            for key, val in six.iteritems(reset):
                if isinstance(val, bool):
                    continue
                if not val.get('success'):
                    msg = val.get('message')
                    if not msg:
                        msg = 'There was an error resetting a syslog config \'{0}\'.' \
                              'Please check debug logs.'.format(val)
                    ret['comment'] = 'Error: {0}'.format(msg)
                    return ret

        ret['changes'].update({'reset_syslog_config':
                              {'old': '',
                               'new': reset_configs}})

    current_firewall = __salt__[esxi_cmd]('get_firewall_status').get(host)
    error = current_firewall.get('Error')
    if error:
        ret['comment'] = 'Error: {0}'.format(error)
        return ret

    current_firewall = current_firewall.get('rulesets').get('syslog')
    if current_firewall != firewall:
        # Only run the command if not using test=True
        if not __opts__['test']:
            enabled = __salt__[esxi_cmd]('enable_firewall_ruleset',
                                         ruleset_enable=firewall,
                                         ruleset_name='syslog').get(host)
            if enabled.get('retcode') != 0:
                err = enabled.get('stderr')
                out = enabled.get('stdout')
                ret['comment'] = 'Error: {0}'.format(err if err else out)
                return ret

        ret['changes'].update({'firewall':
                              {'old': current_firewall,
                               'new': firewall}})

    current_syslog_config = __salt__[esxi_cmd]('get_syslog_config').get(host)
    for key, val in six.iteritems(syslog_configs):
        # The output of get_syslog_config has different keys than the keys
        # Used to set syslog_config values. We need to look them up first.
        try:
            lookup_key = _lookup_syslog_config(key)
        except KeyError:
            ret['comment'] = '\'{0}\' is not a valid config variable.'.format(key)
            return ret

        current_val = current_syslog_config[lookup_key]
        if six.text_type(current_val) != six.text_type(val):
            # Only run the command if not using test=True
            if not __opts__['test']:
                response = __salt__[esxi_cmd]('set_syslog_config',
                                              syslog_config=key,
                                              config_value=val,
                                              firewall=firewall,
                                              reset_service=reset_service).get(host)
                success = response.get(key).get('success')
                if not success:
                    msg = response.get(key).get('message')
                    if not msg:
                        msg = 'There was an error setting syslog config \'{0}\'. ' \
                              'Please check debug logs.'.format(key)
                    ret['comment'] = msg
                    return ret

            if not ret['changes'].get('syslog_config'):
                ret['changes'].update({'syslog_config': {}})
            ret['changes']['syslog_config'].update({key:
                                                   {'old': current_val,
                                                    'new': val}})

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

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

    return ret