Initial commit
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..22bacf8
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,6 @@
+haproxy-formula
+===============
+
+0.0.1 (2015-08-03)
+
+- Initial formula setup
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..6f2b42f
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2014-2015 tcp cloud a.s.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
\ No newline at end of file
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..ab083c8
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,181 @@
+=======
+HAproxy
+=======
+
+The Reliable, High Performance TCP/HTTP Load Balancer. 
+
+Sample pillar
+=============
+
+.. code-block:: yaml
+
+    haproxy:
+      proxy:
+        enabled: True
+        mode: http/tcp
+        max_connections: 1024
+        connect_timeout: 5000
+        client_timeout: 50000
+        server_timeout: 50000
+        listens:
+        - name: https-in
+          bind:
+            address: 0.0.0.0
+            port: 443
+          servers:
+          - name: server1
+            host: 10.0.0.1
+            port: 8443
+          - name: server2
+            host: 10.0.0.2
+            port: 8443
+            params: 'maxconn 256'
+
+Sample pillar with custom logging
+=================================
+
+.. code-block:: yaml
+
+    haproxy:
+      proxy:
+        enabled: True
+        mode: http/tcp
+        logging: syslog
+        max_connections: 1024
+        connect_timeout: 5000
+        client_timeout: 50000
+        server_timeout: 50000
+        listens:
+        - name: https-in
+          bind:
+            address: 0.0.0.0
+            port: 443
+          servers:
+          - name: server1
+            host: 10.0.0.1
+            port: 8443
+          - name: server2
+            host: 10.0.0.2
+            port: 8443
+            params: 'maxconn 256'
+
+.. code-block:: yaml
+
+      haproxy:
+        proxy:
+          enabled: true
+          mode: tcp
+          logging: syslog
+          max_connections: 1024
+          listens:
+          - name: mysql
+            type: mysql
+            binds:
+            - address: 10.0.88.70
+              port: 3306
+            servers:
+            - name: node1
+              host: 10.0.88.13
+              port: 3306
+              params: check inter 15s fastinter 2s downinter 1s rise 5 fall 3
+            - name: node2
+              host: 10.0.88.14
+              port: 3306
+              params: check inter 15s fastinter 2s downinter 1s rise 5 fall 3 backup
+            - name: node3
+              host: 10.0.88.15
+              port: 3306
+              params: check inter 15s fastinter 2s downinter 1s rise 5 fall 3 backup
+          - name: rabbitmq
+            type: rabbitmq
+            binds:
+            - address: 10.0.88.70
+              port: 5672
+            servers:
+            - name: node1
+              host: 10.0.88.13
+              port: 5673
+              params: check inter 5000 rise 2 fall 3 
+            - name: node2
+              host: 10.0.88.14
+              port: 5673
+              params: check inter 5000 rise 2 fall 3 backup
+            - name: node3
+              host: 10.0.88.15
+              port: 5673
+              params: check inter 5000 rise 2 fall 3 backup
+          -name: keystone-1
+           type: general-service
+           bins:
+           - address: 10.0.106.170
+             port: 5000
+           servers:
+           -name: node1
+            host: 10.0.88.13
+            port: 5000
+            params: check
+
+.. code-block:: yaml
+
+      haproxy:
+        proxy:
+          enabled: true
+          mode: tcp
+          logging: syslog
+          max_connections: 1024
+          listens:
+          - name: mysql
+            type: mysql
+            binds:
+            - address: 10.0.88.70
+              port: 3306
+            servers:
+            - name: node1
+              host: 10.0.88.13
+              port: 3306
+              params: check inter 15s fastinter 2s downinter 1s rise 5 fall 3
+            - name: node2
+              host: 10.0.88.14
+              port: 3306
+              params: check inter 15s fastinter 2s downinter 1s rise 5 fall 3 backup
+            - name: node3
+              host: 10.0.88.15
+              port: 3306
+              params: check inter 15s fastinter 2s downinter 1s rise 5 fall 3 backup
+          - name: rabbitmq
+            type: rabbitmq
+            binds:
+            - address: 10.0.88.70
+              port: 5672
+            servers:
+            - name: node1
+              host: 10.0.88.13
+              port: 5673
+              params: check inter 5000 rise 2 fall 3 
+            - name: node2
+              host: 10.0.88.14
+              port: 5673
+              params: check inter 5000 rise 2 fall 3 backup
+            - name: node3
+              host: 10.0.88.15
+              port: 5673
+              params: check inter 5000 rise 2 fall 3 backup
+          -name: keystone-1
+           type: general-service
+           bins:
+           - address: 10.0.106.170
+             port: 5000
+           servers:
+           -name: node1
+            host: 10.0.88.13
+            port: 5000
+            params: check
+
+Read more
+=========
+
+* https://github.com/jesusaurus/hpcs-salt-state/tree/master/haproxy
+* http://www.nineproductions.com/saltstack-ossec-state-using-reactor/ - example reactor usage.
+* https://gist.github.com/tomeduarte/6340205 - example on how to use peer from within a config file (using jinja)
+* http://youtu.be/jJJ8cfDjcTc?t=8m58s - from 9:00 on, a good overview of peer vs mine
+* https://github.com/russki/cluster-agents
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..3b04cfb
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.2
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..37d9e04
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,11 @@
+salt-formula-haproxy (0.2) trusty; urgency=medium
+
+  * First public release
+
+ -- Filip Pytloun <filip.pytloun@tcpcloud.eu>  Tue, 06 Oct 2015 16:38:42 +0200
+
+salt-formula-haproxy (0.1) trusty; urgency=medium
+
+  * Initial release
+
+ -- Ales Komarek <ales.komarek@tcpcloud.eu>  Thu, 13 Aug 2015 23:23:41 +0200
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..624e453
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,15 @@
+Source: salt-formula-haproxy
+Maintainer: Ales Komarek <ales.komarek@tcpcloud.eu>
+Section: admin
+Priority: optional
+Build-Depends: debhelper (>= 9)
+Standards-Version: 3.9.6
+Homepage: http://www.tcpcloud.eu
+Vcs-Browser: https://github.com/tcpcloud/salt-formula-haproxy
+Vcs-Git: https://github.com/tcpcloud/salt-formula-haproxy.git
+
+Package: salt-formula-haproxy
+Architecture: all
+Depends: ${misc:Depends}, salt-master, reclass
+Description: HAproxy salt formula
+ Configure HAproxy service.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..3a21ea3
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,15 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: salt-formula-haproxy
+Upstream-Contact: Ales Komarek <ales.komarek@tcpcloud.eu>
+Source: https://github.com/tcpcloud/salt-formula-haproxy
+
+Files: *
+Copyright: 2014-2015 tcp cloud a.s.
+License: Apache-2.0
+  Copyright (C) 2014-2015 tcp cloud a.s.
+  .
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  .
+  On a Debian system you can find a copy of this license in
+  /usr/share/common-licenses/Apache-2.0.
diff --git a/debian/docs b/debian/docs
new file mode 100644
index 0000000..d585829
--- /dev/null
+++ b/debian/docs
@@ -0,0 +1,3 @@
+README.rst
+CHANGELOG.rst
+VERSION
diff --git a/debian/install b/debian/install
new file mode 100644
index 0000000..28c1330
--- /dev/null
+++ b/debian/install
@@ -0,0 +1,2 @@
+haproxy/*             /usr/share/salt-formulas/env/haproxy/
+metadata/service/*      /usr/share/salt-formulas/reclass/service/haproxy/
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..abde6ef
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,5 @@
+#!/usr/bin/make -f
+
+%:
+	dh $@
+
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/haproxy/files/backend/_admin.cfg b/haproxy/files/backend/_admin.cfg
new file mode 100644
index 0000000..5b64ad8
--- /dev/null
+++ b/haproxy/files/backend/_admin.cfg
@@ -0,0 +1,8 @@
+  mode  http
+  acl  AuthOkay_ReadOnly http_auth(STATSUSERS)
+  acl  AuthOkay_Admin http_auth_group(STATSUSERS) {{ listen.user }}
+  stats  enable
+  stats  refresh 60s
+  stats  uri /
+  stats  http-request auth realm admin_page unless AuthOkay_ReadOnly
+  stats  admin if AuthOkay_Admin
diff --git a/haproxy/files/backend/_contrail-analytics.cfg b/haproxy/files/backend/_contrail-analytics.cfg
new file mode 100644
index 0000000..84daead
--- /dev/null
+++ b/haproxy/files/backend/_contrail-analytics.cfg
@@ -0,0 +1,5 @@
+  balance roundrobin
+  option nolinger
+  option tcp-check
+  tcp-check connect port 6379
+  default-server error-limit 1 on-error mark-down
\ No newline at end of file
diff --git a/haproxy/files/backend/_contrail-api.cfg b/haproxy/files/backend/_contrail-api.cfg
new file mode 100644
index 0000000..0c8fd49
--- /dev/null
+++ b/haproxy/files/backend/_contrail-api.cfg
@@ -0,0 +1,2 @@
+  balance roundrobin
+  option nolinger
\ No newline at end of file
diff --git a/haproxy/files/backend/_contrail-config.cfg b/haproxy/files/backend/_contrail-config.cfg
new file mode 100644
index 0000000..cdc16d1
--- /dev/null
+++ b/haproxy/files/backend/_contrail-config.cfg
@@ -0,0 +1,4 @@
+  mode http
+  stats enable
+  stats uri /
+  stats auth {{ listen.user }}:{{ listen.password }}
\ No newline at end of file
diff --git a/haproxy/files/backend/_general-service.cfg b/haproxy/files/backend/_general-service.cfg
new file mode 100644
index 0000000..946dd4d
--- /dev/null
+++ b/haproxy/files/backend/_general-service.cfg
@@ -0,0 +1,3 @@
+  mode http
+  balance roundrobin
+  option httplog
\ No newline at end of file
diff --git a/haproxy/files/backend/_heat.cfg b/haproxy/files/backend/_heat.cfg
new file mode 100644
index 0000000..0d7c589
--- /dev/null
+++ b/haproxy/files/backend/_heat.cfg
@@ -0,0 +1,3 @@
+  balance source
+  option tcpka
+  option httpchk
\ No newline at end of file
diff --git a/haproxy/files/backend/_horizon.cfg b/haproxy/files/backend/_horizon.cfg
new file mode 100644
index 0000000..70124a1
--- /dev/null
+++ b/haproxy/files/backend/_horizon.cfg
@@ -0,0 +1,9 @@
+  mode http
+  balance  source
+  capture  cookie vgnvisitor= len 32
+  cookie  SERVERID insert indirect nocache
+  option forwardfor
+  option httpchk
+  option httpclose
+  option httplog
+  rspidel ^Set-cookie:\ IP=
\ No newline at end of file
diff --git a/haproxy/files/backend/_http.cfg b/haproxy/files/backend/_http.cfg
new file mode 100644
index 0000000..b7a4a06
--- /dev/null
+++ b/haproxy/files/backend/_http.cfg
@@ -0,0 +1,3 @@
+  mode http
+  balance  roundrobin
+  option  httplog
\ No newline at end of file
diff --git a/haproxy/files/backend/_mysql.cfg b/haproxy/files/backend/_mysql.cfg
new file mode 100644
index 0000000..c041bf5
--- /dev/null
+++ b/haproxy/files/backend/_mysql.cfg
@@ -0,0 +1,9 @@
+  mode tcp
+  balance leastconn
+  option httpchk
+  option tcplog
+  option clitcpka
+  option srvtcpka
+  timeout client  28801s
+  timeout server  28801s
+  option mysql-check user haproxy
\ No newline at end of file
diff --git a/haproxy/files/backend/_openstack-service.cfg b/haproxy/files/backend/_openstack-service.cfg
new file mode 100644
index 0000000..2b90750
--- /dev/null
+++ b/haproxy/files/backend/_openstack-service.cfg
@@ -0,0 +1,3 @@
+  option  httpchk
+  option  httplog
+  option  httpclose
\ No newline at end of file
diff --git a/haproxy/files/backend/_rabbitmq.cfg b/haproxy/files/backend/_rabbitmq.cfg
new file mode 100644
index 0000000..d6a0f80
--- /dev/null
+++ b/haproxy/files/backend/_rabbitmq.cfg
@@ -0,0 +1,5 @@
+  mode tcp
+  balance roundrobin
+  option tcpka
+  timeout client 48h
+  timeout server 48h
\ No newline at end of file
diff --git a/haproxy/files/backend/_stats.cfg b/haproxy/files/backend/_stats.cfg
new file mode 100644
index 0000000..cdc16d1
--- /dev/null
+++ b/haproxy/files/backend/_stats.cfg
@@ -0,0 +1,4 @@
+  mode http
+  stats enable
+  stats uri /
+  stats auth {{ listen.user }}:{{ listen.password }}
\ No newline at end of file
diff --git a/haproxy/files/haproxy.cfg b/haproxy/files/haproxy.cfg
new file mode 100644
index 0000000..424a79d
--- /dev/null
+++ b/haproxy/files/haproxy.cfg
@@ -0,0 +1,182 @@
+{%- set proxy = pillar.haproxy.proxy %}
+{%- set haproxy_logging = pillar.haproxy.proxy.get('logging', "") %}
+
+global
+{%- if grains.os_family == "RedHat" %}
+  chroot  /var/lib/haproxy
+  stats  socket /var/lib/haproxy/stats
+{%- endif %}
+  daemon  
+  maxconn  16000
+  pidfile  /var/run/haproxy.pid
+  user  haproxy
+  group  haproxy
+  spread-checks 4
+  tune.maxrewrite 1024
+  tune.bufsize 32768
+
+
+defaults
+  log  global
+  mode http
+  {%- if haproxy_logging == 'syslog' %}
+  log 127.0.0.1 local0
+  {%- endif %}
+
+  maxconn 8000
+  {#
+  timeout connect {{ proxy.get('connect_timeout', '5000') }}ms
+  timeout client {{ proxy.get('client_timeout', '50000ms') }}ms
+  timeout server {{ proxy.get('server_timeout', '50000ms') }}ms
+  #}
+  option  redispatch
+  retries  3
+  stats  enable
+  timeout http-request 10s
+  timeout queue 1m
+  timeout connect 10s
+  timeout client 1m
+  timeout server 1m
+  timeout check 10s
+
+{%- if proxy.listen.admin_page is defined %}
+
+userlist STATSUSERS
+  group admin users admin
+  user {{ proxy.listen.admin_page.user }} insecure-password {{ proxy.listen.admin_page.password }}
+  user stats insecure-password {{ proxy.listen.admin_page.password }}
+{#
+{%- for listen_name, listen in proxy.get('listen', {}).iteritems() %}
+{%- if listen.user is defined %}
+  user {{ listen.user }} insecure-password {{ listen.password }}
+{%- endif %}
+{%- endfor %}
+#}
+
+{%- endif %}
+
+{%- for listen_name, listen in proxy.get('listen', {}).iteritems() %}
+{%- if listen.get('format', 'listen') == 'listen' %}
+
+listen {{ listen_name }}
+  {%- for bind in listen.binds %}
+  bind {{ bind.address }}:{{ bind.port }}
+  {%- endfor %}
+  {%- if listen.type == 'http' %}
+  mode http
+  balance  roundrobin
+  option  httplog
+  {%- endif %}
+  {%- if listen.type == 'rabbitmq' %}
+  balance roundrobin
+  mode tcp
+  option tcpka
+  timeout client 48h
+  timeout server 48h
+  {%- endif %}
+  {%- if listen.type == 'mysql' %}
+  balance leastconn
+  mode tcp
+  option httpchk
+  option tcplog
+  option clitcpka
+  option srvtcpka
+  timeout client  28801s
+  timeout server  28801s
+  option mysql-check user haproxy
+  {%- endif %}
+  {%- if listen.type == 'horizon' %}
+  balance  source
+  capture  cookie vgnvisitor= len 32
+  cookie  SERVERID insert indirect nocache
+  mode http
+  option forwardfor
+  option httpchk
+  option httpclose
+  option httplog
+  rspidel ^Set-cookie:\ IP=
+  {%- endif %}
+  {%- if listen.type == 'general-service' %}
+  mode http
+  balance  roundrobin
+  option  httplog
+  {%- endif %}
+  {%- if listen.type == 'openstack-service' %}
+  option  httpchk
+  option  httplog
+  option  httpclose
+  {%- endif %}
+  {%- if listen.type == 'heat' %}
+  balance  source
+  option tcpka
+  option httpchk
+  option tcplog
+  {%- endif %}
+  {%- if listen.type == 'contrail-config' %}
+  mode http
+  stats enable
+  stats uri /
+  stats auth {{ listen.user }}:{{ listen.password }}
+  {%- endif %}
+  {%- if listen.type == 'contrail-api' %}
+  option nolinger
+  balance roundrobin
+  {%- endif %}
+  {%- if listen.type == 'contrail-analytics' %}
+  option nolinger
+  balance roundrobin
+  option tcp-check
+  tcp-check connect port 6379
+  default-server error-limit 1 on-error mark-down
+  {%- endif %}    
+  {%- if listen.type == 'stats' %}
+  mode http
+  stats enable
+  stats uri /
+  stats auth {{ listen.user }}:{{ listen.password }}
+  {%- endif %}
+  {%- if listen.type == 'admin' %}
+  mode  http
+  acl  AuthOkay_ReadOnly http_auth(STATSUSERS)
+  acl  AuthOkay_Admin http_auth_group(STATSUSERS) {{ listen.user }}
+  stats  enable
+  stats  refresh 60s
+  stats  uri /
+  stats  http-request auth realm admin_page unless AuthOkay_ReadOnly
+  stats  admin if AuthOkay_Admin
+  {%- endif %}
+  {%- for server in listen.get('servers', []) %}
+  server {{ server.name }} {{ server.host }}:{{ server.port }} {{ server.get('params', '') }}
+  {%- endfor %}
+{%- endif %}
+{%- endfor %}
+
+{%- for listen_name, listen in proxy.get('listen', {}).iteritems() %}
+{%- if listen.get('format', 'listen') == 'end' %}
+
+frontend  {{ listen_name }} {{ listen.binds[0].address }}:{{ listen.binds[0].port }}
+  {%- for acl in listen.get('acls', []) %}
+  {%- for condition in acl.get('conditions', []) %}
+  acl {{ acl.name }} {{ condition.type }} {{ condition.condition }}
+  {%- endfor %}
+  use_backend {{ acl.name }}-backend   if {{ acl.name }}
+  {%- endfor %}
+  default_backend {{ listen_name }}-backend
+
+backend {{ listen_name }}-backend
+  {%- if listen.type == 'http' %}
+  balance roundrobin
+  {%- endif %}
+  {%- for server in listen.get('servers', []) %}
+  server {{ server.get('name', server.host) }} {{ server.host }}:{{ server.port }} {{ server.get('params', '') }}
+  {%- endfor %}
+{%- for acl in listen.get('acls', []) %}
+
+backend {{ acl.name }}-backend
+  balance     roundrobin
+  {%- for server in acl.get('servers', []) %}
+  server {{ server.get('name', server.host) }} {{ server.host }}:{{ server.port }} {{ server.get('params', '') }}
+  {%- endfor %}
+{%- endfor %}
+{%- endif %}
+{%- endfor %}
diff --git a/haproxy/files/haproxy.default b/haproxy/files/haproxy.default
new file mode 100644
index 0000000..2bf3a14
--- /dev/null
+++ b/haproxy/files/haproxy.default
@@ -0,0 +1,5 @@
+
+# Set ENABLED to 1 if you want the init script to start haproxy.
+ENABLED=1
+# Add extra flags here.
+#EXTRAOPTS="-de -m 16"
diff --git a/haproxy/files/logrotate.conf b/haproxy/files/logrotate.conf
new file mode 100644
index 0000000..4957b43
--- /dev/null
+++ b/haproxy/files/logrotate.conf
@@ -0,0 +1,13 @@
+/mnt/log/haproxy.log {
+    weekly
+    missingok
+    rotate 7
+    compress
+    delaycompress
+    notifempty
+    create 640 syslog adm
+    sharedscripts
+    postrotate
+        /etc/init.d/haproxy reload > /dev/null
+    endscript
+}
\ No newline at end of file
diff --git a/haproxy/files/sensu.conf b/haproxy/files/sensu.conf
new file mode 100644
index 0000000..4f373ab
--- /dev/null
+++ b/haproxy/files/sensu.conf
@@ -0,0 +1,45 @@
+{%- from "haproxy/map.jinja" import proxy with context -%}
+{%- from "linux/map.jinja" import network with context -%}
+{%- if grains.ipv4[0] == '127.0.0.1' %}{% set address =  grains.ipv4[1] %}{% else %}{% set address =  grains.ipv4[0] %}{% endif %}
+local_haproxy_server_proc:
+  command: "PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins check_procs -C haproxy -u haproxy -c 1:1"
+  interval: 60
+  occurrences: 1
+  subscribers:
+  - local-haproxy-server
+{# remote_haproxy_proxy_metrics_{{ network.fqdn }}:
+  command: "PATH=$PATH:/etc/sensu/plugins haproxy-metrics.rb -c {{ address }} -P 9600 -u admin -p admin"
+  interval: 60
+  occurrences: 1
+  subscribers:
+  - remote_network
+remote_haproxy_proxy_status_{{ network.fqdn }}:
+  command: "PATH=$PATH:/etc/sensu/plugins check-haproxy.rb -S {{ address }} -P 9600 -u admin -p admin -A"
+  interval: 60
+  occurrences: 1
+  subscribers:
+  - remote_network #}
+{%- for listen_name, listen in proxy.get('listen', {}).iteritems() %}
+{%- if listen.get('check', True) %}
+{%- if listen.binds.0.address|length == 1 or listen.binds.0.address == '0.0.0.0' %}
+{% if grains.ipv4[0] == '127.0.0.1' %}{% set address =  grains.ipv4[1] %}{% else %}{% set address =  grains.ipv4[0] %}{% endif %}
+{%- else %}
+{%- set address = listen.binds.0.address %}
+{%- endif %}
+{%- if listen.type in ['general-service', 'openstack-service', 'http', 'contrail-api', 'admin'] %}
+remote_haproxy_proxy_http_{{ listen_name }}_{{ network.fqdn }}:
+  command: "PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins check_http -H {{ address }} -p {{ listen.binds.0.port }} -w 5 -c 10"
+  interval: 60
+  occurrences: 1
+  subscribers:
+  - remote-network
+{%- else %}
+remote_haproxy_proxy_tcp_{{ listen_name }}_{{ network.fqdn }}:
+  command: "PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins check_tcp -H {{ address }} -p {{ listen.binds.0.port }} -w 5 -c 10"
+  interval: 60
+  occurrences: 1
+  subscribers:
+  - remote-network
+{%- endif %}
+{%- endif %}
+{%- endfor %}
\ No newline at end of file
diff --git a/haproxy/init.sls b/haproxy/init.sls
new file mode 100644
index 0000000..f7fcb79
--- /dev/null
+++ b/haproxy/init.sls
@@ -0,0 +1,5 @@
+
+{% if pillar.haproxy.proxy is defined %}
+include:
+- haproxy.proxy
+{% endif %}
diff --git a/haproxy/map.jinja b/haproxy/map.jinja
new file mode 100644
index 0000000..2c4ec04
--- /dev/null
+++ b/haproxy/map.jinja
@@ -0,0 +1,10 @@
+{% set proxy = salt['grains.filter_by']({
+    'Debian': {
+        'pkgs': ['haproxy'],
+        'service': 'haproxy',
+    },
+    'RedHat': {
+        'pkgs': ['haproxy'],
+        'service': 'haproxy',
+    },
+}, merge=salt['pillar.get']('haproxy:proxy')) %}
diff --git a/haproxy/proxy.sls b/haproxy/proxy.sls
new file mode 100644
index 0000000..2fd6d72
--- /dev/null
+++ b/haproxy/proxy.sls
@@ -0,0 +1,33 @@
+{%- from "haproxy/map.jinja" import proxy with context %}
+{%- if proxy.enabled %}
+
+haproxy_packages:
+  pkg.installed:
+  - names: {{ proxy.pkgs }}
+
+/etc/default/haproxy:
+  file.managed:
+  - source: salt://haproxy/files/haproxy.default
+  - require:
+    - pkg: haproxy_packages
+
+/etc/haproxy/haproxy.cfg:
+  file.managed:
+  - source: salt://haproxy/files/haproxy.cfg
+  - template: jinja
+  - require:
+    - pkg: haproxy_packages
+
+net.ipv4.ip_nonlocal_bind:
+  sysctl.present:
+    - value: 1
+
+haproxy_service:
+  service.running:
+  - name: {{ proxy.service }}
+  - enable: true
+  - watch:
+    - file: /etc/haproxy/haproxy.cfg
+    - file: /etc/default/haproxy
+
+{%- endif %}
\ No newline at end of file
diff --git a/metadata/service/proxy/admin.yml b/metadata/service/proxy/admin.yml
new file mode 100644
index 0000000..e64949c
--- /dev/null
+++ b/metadata/service/proxy/admin.yml
@@ -0,0 +1,14 @@
+applications:
+- haproxy
+parameters:
+  haproxy:
+    proxy:
+      listen:
+        admin_page:
+          type: admin
+          check: false
+          binds:
+          - address: '*'
+            port: 9600
+          user: admin
+          password: admin
diff --git a/metadata/service/proxy/single.yml b/metadata/service/proxy/single.yml
new file mode 100644
index 0000000..d0a7cfa
--- /dev/null
+++ b/metadata/service/proxy/single.yml
@@ -0,0 +1,9 @@
+applications:
+- haproxy
+parameters:
+  haproxy:
+    proxy:
+      enabled: true
+      mode: tcp
+      logging: syslog
+      max_connections: 1024