{%- from "rsyslog/map.jinja" import global with context -%}

{% for modname in global.modules -%}
$ModLoad {{ modname }}
{% endfor -%}
{% if global.preserve_fqdn == true -%}
$PreserveFQDN on
{% else -%}
$PreserveFQDN off
{% endif -%}
{% if global.non_kernel_facility is defined and global.non_kernel_facility == true -%}
$KLogPermitNonKernelFacility on
{% endif -%}
{% if global.omit_local_logging is defined and global.omit_local_logging == true -%}
$OmitLocalLogging on
{% endif -%}
{% if global.msg_reduction == true -%}
$RepeatedMsgReduction on
{% endif -%}
{% if global.max_message_size is defined -%}
$MaxMessageSize {{ global.max_message_size }}
{% endif -%}
{% if global.system_log_rate_limit_interval is defined -%}
$SystemLogRateLimitInterval {{ global.system_log_rate_limit_interval }}
{% endif -%}
{% if global.system_log_rateLimit_burst is defined -%}
$SystemLogRateLimitBurst {{ global.system_log_rateLimit_burst }}
{% endif -%}
$DirCreateMode {{ global.perm_dir }}
$PrivDropToUser {{ global.run_user }}
$PrivDropToGroup {{ global.run_group }}
$WorkDirectory {{ global.spool_dir }}

{% if global.format is defined -%}
$Template {{ global.format.name }}, "{{ global.format.template }}"
$ActionFileDefaultTemplate {{ global.format.name }}
{% else -%}
$template RSYSLOG_TraditionalFileFormat
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
{% endif -%}

{% if global.rainerscript is defined -%}

{%- set rainerscript = global.get('rainerscript', {}) -%}

{%- for mod,parameter in rainerscript.get('module', {}).iteritems() %}
module(load="{{ mod }}"{%- for name,value in parameter.iteritems() %} {{name}}="{{value}}"{%- endfor -%})
{%- endfor %}

{%- for name,template in rainerscript.get('template', {}).iteritems() %}
template(name="{{ name }}" {%- for name,value in template.parameter.iteritems() %} {{name}}="{{value}}"{%- endfor -%})
{%- if template.description is defined -%}{ {{ template.description }} } {%- endif -%}
{%- endfor %}

{%- for name,ruleset in rainerscript.get('ruleset', {}).iteritems() %}
ruleset(name="{{ name }}"){
{{ ruleset.description }}
}
{%- endfor %}

{%- for type,input in rainerscript.get('input', {}).iteritems() %}
{%- for name,parameter in input.iteritems() %}
input(type="{{ type }}"{%- for name,value in parameter.iteritems() %} {{name}}="{{value}}"{%- endfor -%})
{%- endfor %}
{%- endfor %}
{% endif -%}

{% if global.output.remote is defined %}
{% for name,config in global.output.remote.iteritems() if config.get('enabled', False) -%}
{{ config['filter'] }}      {{ config['action'] }}
{% endfor -%}
{% endif -%}

{# Additional configurations should be included after defining the global format otherwise they won't benefit from it #}
$IncludeConfig {{ global.rsyslog_d }}/*.conf

{%- set file_groups = {
  'stop': {},
  'other': {}
} -%}

{%- for name,config in global.output.file.iteritems() if config.get('enabled', False) %}
{%- if config.get('stop_processing', False) -%}
{%- do file_groups.stop.update({name: config}) -%}
{%- else -%}
{%- do file_groups.other.update({name: config}) -%}
{%- endif -%}
{%- if config.template is defined %}
$Template {{ name|replace('/', '_') }}, "{{ config.template }}"
{%- endif -%}
{%- endfor -%}

{%- macro rsyslog_output_file(files) -%}
{%- for name, config in files.items() %}
{% if config.owner is defined -%}
$FileOwner {{ config['owner'] }}
{% endif -%}
{% if config.group is defined -%}
$FileGroup {{ config['group'] }}
{% endif -%}
{% if config.createmode is defined -%}
$FileCreateMode {{ config['createmode'] }}
{% endif -%}
{% if config.umask is defined -%}
$Umask {{ config['umask'] }}
{% endif -%}
{{ config['filter'] }}     {% if config.sync == true %}-{% endif %}{{ name }}{%if config.template is defined %};{{ name|replace('/', '_') }}{% endif %}
{%- if config.get('stop_processing', False) %}
&stop
{%- endif %}
{% endfor -%}
{%- endmacro %}

{{ rsyslog_output_file(file_groups.stop) }}
{{ rsyslog_output_file(file_groups.other) }}

{% if global.output.console is defined %}
{% for name,config in global.output.console.iteritems() if config.get('enabled', False) -%}
{{ config['filter'] }}      {{ config['action'] }}
{% endfor -%}
{% endif -%}
