Parameterize all global configuration parameters

  - Keeps full backwards compatibility
  - Includes fixes from https://gerrit.mcp.mirantis.com/#/c/40867/

Related: PROD-29206
Fixes: PROD-29088

Change-Id: I3d71c265e7975060d9804288b341775acccdf9da
(cherry picked from commit eef51a15f7018aee0d46271fee3cff7ee0408e25)
(cherry picked from commit 6d337fa48ac0aaa4ac190d44d3591b95ee1209d1)
diff --git a/.kitchen.yml b/.kitchen.yml
index 2e0cae8..e66639c 100644
--- a/.kitchen.yml
+++ b/.kitchen.yml
@@ -77,4 +77,9 @@
     provisioner:
       pillars-from-files:
         haproxy.sls: tests/pillar/single_rate_limiting.sls
+
+  - name: single_global_parameters
+    provisioner:
+      pillars-from-files:
+        haproxy.sls: tests/pillar/single_global_parameters.sls
 # vim: ft=yaml sw=2 ts=2 sts=2 tw=125
diff --git a/README.rst b/README.rst
index c970cb6..659d66e 100644
--- a/README.rst
+++ b/README.rst
@@ -678,6 +678,55 @@
                 enabled: true
                 value: use_backend nova_metadata_api-rate_limit if mark_seen too_many_requests_6 x_tenant_id
 
+Pillar demostrating all global variables which are parametrized
+
+  All values may be defined as a single element or a list of elements with the same keyword
+  Keyword is added automatically and should not be included in the value
+
+.. code-block:: yaml
+
+  haproxy:
+    proxy:
+      global:
+        chroot: /var/lib/haproxy
+        daemon: true
+        gid: ''
+        group: haproxy
+        cpu-map:
+        - '0 1'
+        - '1 2'
+        log:
+        - '/dev/log local0'
+        - '/dev/log local1 notice'
+        log-send-hostname: ''
+        nbproc: 5
+        pidfile: '/var/run/haproxy.pid'
+        uid: ''
+        ulimit-n: ''
+        user: 'haproxy'
+        stats:
+        - 'socket /var/run/new.sock mode 660 level admin'
+        - 'timeout 30s'
+        - 'bind-process 1 2'
+        node: ''
+        description: ''
+        maxconn: 25000
+        maxpipes: ''
+        noepoll: ''
+        nokqueue: ''
+        nopoll: ''
+        nosepoll: ''
+        nosplice: ''
+        spread-checks: 4
+        tune_bufsize: 32768
+        tune_chksize: ''
+        tune_maxaccept: ''
+        tune_maxpollevents: ''
+        tune_maxrewrite: 1024
+        tune_rcvbuf_client: ''
+        tune_rcvbuf_server: ''
+        tune_sndbuf_client: ''
+        tune_sndbuf_server: ''
 
 Read more
 =========
diff --git a/haproxy/files/haproxy.cfg b/haproxy/files/haproxy.cfg
index f0896a3..de8d89c 100644
--- a/haproxy/files/haproxy.cfg
+++ b/haproxy/files/haproxy.cfg
@@ -1,28 +1,18 @@
 {%- from "haproxy/map.jinja" import proxy, invalid_section_options with context -%}
 
 global
-{%- if proxy.nbproc is defined %}
-  nbproc {{ proxy.nbproc }}
-{%- endif %}
-{%- for process, cpu in proxy.get('cpu_map', {}).iteritems() %}
-  cpu-map {{ process }} {{ cpu }}
+{%- for param_name, param in proxy.global.items()|sort %} {# Iterate through all global parameters #}
+  {%- if param is iterable and param is not string and param|length > 0 %} {# Param is a list of values #}
+    {%- for value in param %} {# Iterate through list #}
+  {{ param_name|replace('_', '.') }} {{ value }} {# Add each value from list #}
+    {%- endfor %}
+  {%- elif param == true or param|lower == 'true' %} {# Param is boolean and true #}
+  {{ param_name|replace('_', '.') }} {# Add param name if value is true #}
+  {%- elif (param is string and param != '' and param|lower != 'false') or (param is number and param != false) %} {# Param is a string and is not empty or is a number #}
+  {{ param_name|replace('_', '.') }} {{ param }}  {# Add a string value #}
+  {%- endif %}
 {%- endfor %}
-  log /dev/log  local0
-  log /dev/log  local1 notice
-  chroot /var/lib/haproxy
-  stats  socket {{ proxy.stats_socket }} mode 660 level admin
-  stats timeout 30s
-{%- if proxy.stats_bind_process is defined %}
-  stats bind-process {{ proxy.stats_bind_process }}
-{%- endif %}
-  user  haproxy
-  group haproxy
-  daemon
-  pidfile  /var/run/haproxy.pid
-  spread-checks 4
-  tune.maxrewrite 1024
-  tune.bufsize 32768
-  maxconn  {{ proxy.global.maxconn }}
+
   {%- if salt['pkg.version']('haproxy')[:3] >= '1.6' %}
   # SSL options
   ca-base /etc/haproxy/ssl
diff --git a/haproxy/map.jinja b/haproxy/map.jinja
index a6f0078..4167a2f 100644
--- a/haproxy/map.jinja
+++ b/haproxy/map.jinja
@@ -1,19 +1,50 @@
+{% set stats_socket_default = '/run/haproxy/admin.sock' %}
+{% set cpu_map_pillar = salt['pillar.get'](key='haproxy:proxy:cpu_map', default={}) %}
+{% set cpu_map_default = [] %}
+
+{% if cpu_map_pillar|length > 0 %}
+    {%- for process, cpu in cpu_map_pillar.items() %}
+        {{ cpu_map_default.append(process|string+' '+cpu|string) }}
+    {%- endfor %}
+{% endif %}
+
+{% set global_parameters = {
+    'chroot': '/var/lib/haproxy',
+    'daemon': true,
+    'group': 'haproxy',
+    'cpu-map': cpu_map_pillar,
+    'log': [
+        '/dev/log local0',
+        '/dev/log local1 notice',
+    ],
+    'log-send-hostname': '',
+    'nbproc': salt['pillar.get'](key='haproxy:proxy:nbproc', default=''),
+    'pidfile': '/var/run/haproxy.pid',
+    'user': 'haproxy',
+    'stats': [
+        'socket ' + salt['pillar.get'](key='haproxy:proxy:stats_socket', default=stats_socket_default) + ' mode 660 level admin',
+        'timeout 30s',
+        'bind-process ' + salt['pillar.get'](key='haproxy:proxy:stats_bind_process', default=''),
+    ],
+    'maxconn': 25000,
+    'spread-checks': 4,
+    'tune_bufsize': 32768,
+    'tune_maxrewrite': 1024,
+    }
+%}
+
 {% set proxy = salt['grains.filter_by']({
     'Debian': {
         'pkgs': ['haproxy'],
         'service': 'haproxy',
-        'stats_socket': '/run/haproxy/admin.sock',
-        'global': {
-          'maxconn' : 25000
-        }
+        'stats_socket': stats_socket_default,
+        'global': global_parameters
     },
     'RedHat': {
         'pkgs': ['haproxy'],
         'service': 'haproxy',
-        'stats_socket': '/var/lib/haproxy/stats',
-        'global': {
-          'maxconn' : 25000
-        }
+        'stats_socket': stats_socket_default,
+        'global': global_parameters
     },
 }, merge=salt['pillar.get']('haproxy:proxy')) %}
 
diff --git a/tests/pillar/single_global_parameters.sls b/tests/pillar/single_global_parameters.sls
new file mode 100644
index 0000000..56d3f08
--- /dev/null
+++ b/tests/pillar/single_global_parameters.sls
@@ -0,0 +1,59 @@
+haproxy:
+  proxy:
+    enabled: true
+    mode: tcp
+    logging: syslog
+    max_connections: 1024
+    nbproc: 4
+    global:
+      chroot: /var/lib/haproxy
+      daemon: true
+      gid: ''
+      group: haproxy
+      cpu-map:
+      - '1 9'
+      - '2 8'
+      log:
+      - '/dev/log local1'
+      - '/dev/log local2 notice'
+      log-send-hostname: ''
+      nbproc: 5
+      pidfile: '/var/run/new.pid'
+      uid: ''
+      ulimit-n: 12
+      user: 'haproxy'
+      stats:
+      - 'socket /var/run/new.sock mode 660 level admin'
+      - 'timeout 60s'
+      - 'bind-process 2 3'
+      - 'testing stat'
+      node: NodeName
+      description: Description
+      maxconn: 99999
+      maxpipes: 1234
+      noepoll: 2345
+      nokqueue: 3456
+      nopoll: 4567
+      nosepoll: 5678
+      nosplice: 6789
+      spread-checks: 6
+      tune_bufsize: 18000
+      tune_chksize: 7890
+      tune_maxaccept: 8901
+      tune_maxpollevents: 9012
+      tune_maxrewrite: 2048
+      tune_rcvbuf_client: 1245
+      tune_rcvbuf_server: 2356
+      tune_sndbuf_client: 3467
+      tune_sndbuf_server: 4578
+    cpu_map:
+      1: 0
+      2: 1
+      3: 2
+      4: 3
+    stats_bind_process: "1 2"
+
+# For haproxy/meta/sensu.yml
+linux:
+  network:
+    fqdn: linux.ci.local