Merge pull request #27 from damjanek/master

Default timeout for mysql and rabbit is too large
diff --git a/.gitignore b/.gitignore
index 1bfce6e..aa8e42a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
+.kitchen
 tests/build/
 *.swp
 *.pyc
-.ropeproject
\ No newline at end of file
+.ropeproject
diff --git a/.kitchen.yml b/.kitchen.yml
new file mode 100644
index 0000000..f46053f
--- /dev/null
+++ b/.kitchen.yml
@@ -0,0 +1,63 @@
+---
+driver:
+  name: docker
+  hostname: haproxy.ci.local
+  use_sudo: false
+
+provisioner:
+  name: salt_solo
+  salt_install: bootstrap
+  salt_bootstrap_url: https://bootstrap.saltstack.com
+  salt_version: latest
+  require_chef: false
+  log_level: error
+  formula: haproxy
+  grains:
+    noservices: True
+  state_top:
+    base:
+      "*":
+        - haproxy
+  pillars:
+    top.sls:
+      base:
+        "*":
+          - haproxy
+
+verifier:
+  name: inspec
+  sudo: true
+
+platforms:
+  - name: <%=ENV['PLATFORM'] || 'ubuntu-xenial'%>
+    driver_config:
+      image: <%=ENV['PLATFORM'] || 'trevorj/salty-whales:xenial'%>
+      platform: ubuntu
+
+suites:
+
+  - name: admin
+    provisioner:
+      pillars-from-files:
+        haproxy.sls: tests/pillar/admin.sls
+
+  - name: single_contrail
+    provisioner:
+      pillars-from-files:
+        haproxy.sls: tests/pillar/single_contrail.sls
+
+  - name: single_general_service
+    provisioner:
+      pillars-from-files:
+        haproxy.sls: tests/pillar/single_general_service.sls
+
+  - name: single_openstack_service
+    provisioner:
+      pillars-from-files:
+        haproxy.sls: tests/pillar/single_openstack_service.sls
+
+  - name: stats
+    provisioner:
+      pillars-from-files:
+        haproxy.sls: tests/pillar/stats.sls
+# vim: ft=yaml sw=2 ts=2 sts=2 tw=125
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..4f34af2
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,40 @@
+sudo: required
+services:
+  - docker
+
+install:
+  - pip install PyYAML
+  - pip install virtualenv
+  - |
+    test -e Gemfile || cat <<EOF > Gemfile
+    source 'https://rubygems.org'
+    gem 'rake'
+    gem 'test-kitchen'
+    gem 'kitchen-docker'
+    gem 'kitchen-inspec'
+    gem 'inspec'
+    gem 'kitchen-salt', :git => 'https://github.com/salt-formulas/kitchen-salt.git'
+  - bundle install
+
+env:
+    - PLATFORM=trevorj/salty-whales:trusty
+    - PLATFORM=trevorj/salty-whales:xenial
+
+
+before_script:
+  - set -o pipefail
+  - make test | tail
+
+script:
+  - test ! -e .kitchen.yml || bundle exec kitchen test -t tests/integration
+
+notifications:
+  webhooks:
+    urls:
+      - https://webhooks.gitter.im/e/6123573504759330786b
+    on_success: change  # options: [always|never|change] default: always
+    on_failure: never  # options: [always|never|change] default: always
+    on_start: never     # options: [always|never|change] default: always
+    on_cancel: never    # options: [always|never|change] default: always
+    on_error: never    # options: [always|never|change] default: always
+  email: false
diff --git a/Makefile b/Makefile
index fc83783..1043fbe 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,38 @@
 DESTDIR=/
 SALTENVDIR=/usr/share/salt-formulas/env
 RECLASSDIR=/usr/share/salt-formulas/reclass
-FORMULANAME=$(shell grep name: metadata.yml|head -1|cut -d : -f 2|grep -Eo '[a-z0-9\-]*')
+FORMULANAME=$(shell grep name: metadata.yml|head -1|cut -d : -f 2|grep -Eo '[a-z0-9\-\_]*')
+VERSION=$(shell grep version: metadata.yml|head -1|cut -d : -f 2|grep -Eo '[a-z0-9\.\-\_]*')
+VERSION_MAJOR := $(shell echo $(VERSION)|cut -d . -f 1-2)
+VERSION_MINOR := $(shell echo $(VERSION)|cut -d . -f 3)
+
+NEW_MAJOR_VERSION ?= $(shell date +%Y.%m|sed 's,\.0,\.,g')
+NEW_MINOR_VERSION ?= $(shell /bin/bash -c 'echo $$[ $(VERSION_MINOR) + 1 ]')
+
+MAKE_PID := $(shell echo $$PPID)
+JOB_FLAG := $(filter -j%, $(subst -j ,-j,$(shell ps T | grep "^\s*$(MAKE_PID).*$(MAKE)")))
+
+ifneq ($(subst -j,,$(JOB_FLAG)),)
+JOBS := $(subst -j,,$(JOB_FLAG))
+else
+JOBS := 1
+endif
+
+KITCHEN_LOCAL_YAML?=.kitchen.yml
+KITCHEN_OPTS?="--concurrency=$(JOBS)"
+KITCHEN_OPTS_CREATE?=""
+KITCHEN_OPTS_CONVERGE?=""
+KITCHEN_OPTS_VERIFY?=""
+KITCHEN_OPTS_TEST?=""
 
 all:
 	@echo "make install - Install into DESTDIR"
 	@echo "make test    - Run tests"
+	@echo "make kitchen - Run Kitchen CI tests (create, converge, verify)"
 	@echo "make clean   - Cleanup after tests run"
+	@echo "make release-major  - Generate new major release"
+	@echo "make release-minor  - Generate new minor release"
+	@echo "make changelog      - Show changes since last release"
 
 install:
 	# Formula
@@ -14,6 +40,7 @@
 	cp -a $(FORMULANAME) $(DESTDIR)/$(SALTENVDIR)/
 	[ ! -d _modules ] || cp -a _modules $(DESTDIR)/$(SALTENVDIR)/
 	[ ! -d _states ] || cp -a _states $(DESTDIR)/$(SALTENVDIR)/ || true
+	[ ! -d _grains ] || cp -a _grains $(DESTDIR)/$(SALTENVDIR)/ || true
 	# Metadata
 	[ -d $(DESTDIR)/$(RECLASSDIR)/service/$(FORMULANAME) ] || mkdir -p $(DESTDIR)/$(RECLASSDIR)/service/$(FORMULANAME)
 	cp -a metadata/service/* $(DESTDIR)/$(RECLASSDIR)/service/$(FORMULANAME)
@@ -21,6 +48,71 @@
 test:
 	[ ! -d tests ] || (cd tests; ./run_tests.sh)
 
+release-major: check-changes
+	@echo "Current version is $(VERSION), new version is $(NEW_MAJOR_VERSION)"
+	@[ $(VERSION_MAJOR) != $(NEW_MAJOR_VERSION) ] || (echo "Major version $(NEW_MAJOR_VERSION) already released, nothing to do. Do you want release-minor?" && exit 1)
+	echo "$(NEW_MAJOR_VERSION)" > VERSION
+	sed -i 's,version: .*,version: "$(NEW_MAJOR_VERSION)",g' metadata.yml
+	[ ! -f debian/changelog ] || dch -v $(NEW_MAJOR_VERSION) -m --force-distribution -D `dpkg-parsechangelog -S Distribution` "New version"
+	make genchangelog-$(NEW_MAJOR_VERSION)
+	(git add -u; git commit -m "Version $(NEW_MAJOR_VERSION)")
+	git tag -s -m $(NEW_MAJOR_VERSION) $(NEW_MAJOR_VERSION)
+
+release-minor: check-changes
+	@echo "Current version is $(VERSION), new version is $(VERSION_MAJOR).$(NEW_MINOR_VERSION)"
+	echo "$(VERSION_MAJOR).$(NEW_MINOR_VERSION)" > VERSION
+	sed -i 's,version: .*,version: "$(VERSION_MAJOR).$(NEW_MINOR_VERSION)",g' metadata.yml
+	[ ! -f debian/changelog ] || dch -v $(VERSION_MAJOR).$(NEW_MINOR_VERSION) -m --force-distribution -D `dpkg-parsechangelog -S Distribution` "New version"
+	make genchangelog-$(VERSION_MAJOR).$(NEW_MINOR_VERSION)
+	(git add -u; git commit -m "Version $(VERSION_MAJOR).$(NEW_MINOR_VERSION)")
+	git tag -s -m $(NEW_MAJOR_VERSION) $(VERSION_MAJOR).$(NEW_MINOR_VERSION)
+
+check-changes:
+	@git log --pretty=oneline --decorate $(VERSION)..HEAD | grep -Eqc '.*' || (echo "No new changes since version $(VERSION)"; exit 1)
+
+changelog:
+	git log --pretty=short --invert-grep --grep="Merge pull request" --decorate $(VERSION)..HEAD
+
+genchangelog: genchangelog-$(VERSION_MAJOR).$(NEW_MINOR_VERSION)
+
+genchangelog-%:
+	$(eval NEW_VERSION := $(patsubst genchangelog-%,%,$@))
+	(echo "=========\nChangelog\n=========\n"; \
+	(echo $(NEW_VERSION);git tag) | sort -r | grep -E '^[0-9\.]+' | while read i; do \
+	    cur=$$i; \
+	    test $$i = $(NEW_VERSION) && i=HEAD; \
+	    prev=`(echo $(NEW_VERSION);git tag)|sort|grep -E '^[0-9\.]+'|grep -B1 "$$cur\$$"|head -1`; \
+	    echo "Version $$cur\n=============================\n"; \
+	    git log --pretty=short --invert-grep --grep="Merge pull request" --decorate $$prev..$$i; \
+	    echo; \
+	done) > CHANGELOG.rst
+
+kitchen-check:
+	@[ -e $(KITCHEN_LOCAL_YAML) ] || (echo "Kitchen tests not available, there's no $(KITCHEN_LOCAL_YAML)." && exit 1)
+
+kitchen: kitchen-check kitchen-create kitchen-converge kitchen-verify kitchen-list
+
+kitchen-create: kitchen-check
+	kitchen create ${KITCHEN_OPTS} ${KITCHEN_OPTS_CREATE}
+	[ "$(shell echo $(KITCHEN_LOCAL_YAML)|grep -Eo docker)" = "docker" ] || sleep 120
+
+kitchen-converge: kitchen-check
+	kitchen converge ${KITCHEN_OPTS} ${KITCHEN_OPTS_CONVERGE} &&\
+	kitchen converge ${KITCHEN_OPTS} ${KITCHEN_OPTS_CONVERGE}
+
+kitchen-verify: kitchen-check
+	[ ! -d tests/integration ] || kitchen verify -t tests/integration ${KITCHEN_OPTS} ${KITCHEN_OPTS_VERIFY}
+	[ -d tests/integration ]   || kitchen verify ${KITCHEN_OPTS} ${KITCHEN_OPTS_VERIFY}
+
+kitchen-test: kitchen-check
+	[ ! -d tests/integration ] || kitchen test -t tests/integration ${KITCHEN_OPTS} ${KITCHEN_OPTS_TEST}
+	[ -d tests/integration ]   || kitchen test ${KITCHEN_OPTS} ${KITCHEN_OPTS_TEST}
+
+kitchen-list: kitchen-check
+	kitchen list
+
 clean:
+	[ ! -x "$(shell which kitchen)" ] || kitchen destroy
+	[ ! -d .kitchen ] || rm -rf .kitchen
 	[ ! -d tests/build ] || rm -rf tests/build
 	[ ! -d build ] || rm -rf build
diff --git a/README.rst b/README.rst
index f52c0d8..108398e 100644
--- a/README.rst
+++ b/README.rst
@@ -252,6 +252,77 @@
                 port: 8082
                 params: backup check
 
+It's also possible to use multiple certificates for one listener (eg. when
+it's bind on multiple interfaces):
+
+.. code-block:: yaml
+
+    haproxy:
+      proxy:
+        listen:
+          dummy_site:
+            mode: http
+            binds:
+              - address: 127.0.0.1
+                port: 8080
+                ssl:
+                  enabled: true
+                  key: |
+                    my super secret key follows
+                  cert: |
+                    certificate
+                  chain: |
+                    CA chain (if any)
+              - address: 127.0.1.1
+                port: 8081
+                ssl:
+                  enabled: true
+                  key: |
+                    my super secret key follows
+                  cert: |
+                    certificate
+                  chain: |
+                    CA chain (if any)
+
+Definition above will result in creation of ``/etc/haproxy/ssl/dummy_site``
+directory with files ``1-all.pem`` and ``2-all.pem`` (per binds).
+
+Custom listener with tcp-check options specified (for Redis cluster with Sentinel)
+
+.. code-block:: yaml
+
+  haproxy:
+    proxy:
+      listen:
+        redis_cluster:
+          service_name: redis
+          health-check:
+            tcp:
+              enabled: True
+              options:
+                - send PING\r\n
+                - expect string +PONG
+                - send info\ replication\r\n
+                - expect string role:master
+                - send QUIT\r\n
+                - expect string +OK
+          binds:
+            - address: ${_param:cluster_address}
+              port: 6379
+          servers:
+            - name: ${_param:cluster_node01_name}
+              host: ${_param:cluster_node01_address}
+              port: 6379
+              params: check inter 1s
+            - name: ${_param:cluster_node02_name}
+              host: ${_param:cluster_node02_address}
+              port: 6379
+              params: check inter 1s
+            - name: ${_param:cluster_node03_name}
+              host: ${_param:cluster_node03_address}
+              port: 6379
+              params: check inter 1s
+
 Read more
 =========
 
@@ -260,3 +331,36 @@
 * 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
+
+Documentation and Bugs
+======================
+
+To learn how to install and update salt-formulas, consult the documentation
+available online at:
+
+    http://salt-formulas.readthedocs.io/
+
+In the unfortunate event that bugs are discovered, they should be reported to
+the appropriate issue tracker. Use Github issue tracker for specific salt
+formula:
+
+    https://github.com/salt-formulas/salt-formula-haproxy/issues
+
+For feature requests, bug reports or blueprints affecting entire ecosystem,
+use Launchpad salt-formulas project:
+
+    https://launchpad.net/salt-formulas
+
+You can also join salt-formulas-users team and subscribe to mailing list:
+
+    https://launchpad.net/~salt-formulas-users
+
+Developers wishing to work on the salt-formulas projects should always base
+their work on master branch and submit pull request against specific formula.
+
+    https://github.com/salt-formulas/salt-formula-haproxy
+
+Any questions or feedback is always welcome so feel free to join our IRC
+channel:
+
+    #salt-formulas @ irc.freenode.net
diff --git a/haproxy/files/grafana_dashboards/haproxy_influxdb.json b/haproxy/files/grafana_dashboards/haproxy_influxdb.json
index b73bae8..d528cb0 100644
--- a/haproxy/files/grafana_dashboards/haproxy_influxdb.json
+++ b/haproxy/files/grafana_dashboards/haproxy_influxdb.json
@@ -245,7 +245,7 @@
               "interval": "",
               "measurement": "haproxy_uptime",
               "policy": "default",
-              "query": "SELECT mean(\"value\") FROM \"haproxy_uptime\" WHERE \"hostname\" =~ /$server/ AND $timeFilter GROUP BY time($interval)",
+              "query": "SELECT mean(\"value\") FROM \"haproxy_uptime\" WHERE \"hostname\" =~ /^$server/ AND $timeFilter GROUP BY time($interval)",
               "rawQuery": false,
               "refId": "A",
               "resultFormat": "time_series",
@@ -267,7 +267,13 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             }
@@ -349,7 +355,7 @@
               "groupBy": [],
               "measurement": "haproxy_backend_status",
               "policy": "default",
-              "query": "SELECT last(\"value\") FROM \"haproxy_backend_status\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /^$service$/ AND $timeFilter",
+              "query": "SELECT last(\"value\") FROM \"haproxy_backend_status\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /^$service$/ AND $timeFilter",
               "rawQuery": false,
               "refId": "A",
               "resultFormat": "time_series",
@@ -371,12 +377,18 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "key": "backend",
                   "operator": "=~",
                   "value": "/^$service$/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             }
@@ -546,7 +558,7 @@
               ],
               "measurement": "haproxy_connections",
               "policy": "default",
-              "query": "SELECT mean(\"value\") FROM \"haproxy_connections\" WHERE \"hostname\" =~ /$server/ AND $timeFilter GROUP BY time($interval) fill(null)",
+              "query": "SELECT mean(\"value\") FROM \"haproxy_connections\" WHERE \"hostname\" =~ /^$server/ AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "A",
               "resultFormat": "time_series",
@@ -567,7 +579,13 @@
               "tags": [
                 {
                   "key": "hostname",
-                  "value": "/$server/"
+                  "value": "/^$server/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -593,7 +611,7 @@
               "hide": false,
               "measurement": "haproxy_pipes_free",
               "policy": "default",
-              "query": "SELECT mean(\"value\") FROM \"haproxy_pipes_free\" WHERE \"hostname\" =~ /$server/ AND $timeFilter GROUP BY time($interval) fill(null)",
+              "query": "SELECT mean(\"value\") FROM \"haproxy_pipes_free\" WHERE \"hostname\" =~ /^$server/ AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "B",
               "resultFormat": "time_series",
@@ -614,7 +632,13 @@
               "tags": [
                 {
                   "key": "hostname",
-                  "value": "/$server/"
+                  "value": "/^$server/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ],
               "target": ""
@@ -642,7 +666,7 @@
               "interval": "",
               "measurement": "haproxy_pipes_used",
               "policy": "default",
-              "query": "SELECT mean(\"value\") FROM \"haproxy_pipes_used\" WHERE \"hostname\" =~ /$server/ AND $timeFilter GROUP BY time($interval) fill(null)",
+              "query": "SELECT mean(\"value\") FROM \"haproxy_pipes_used\" WHERE \"hostname\" =~ /^$server/ AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "C",
               "resultFormat": "time_series",
@@ -663,7 +687,13 @@
               "tags": [
                 {
                   "key": "hostname",
-                  "value": "/$server/"
+                  "value": "/^$server/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ],
               "target": ""
@@ -690,7 +720,7 @@
               "interval": "",
               "measurement": "haproxy_tasks",
               "policy": "default",
-              "query": "SELECT mean(\"value\") FROM \"haproxy_tasks\" WHERE \"hostname\" =~ /$server/ AND $timeFilter GROUP BY time($interval) fill(null)",
+              "query": "SELECT mean(\"value\") FROM \"haproxy_tasks\" WHERE \"hostname\" =~ /^$server/ AND $timeFilter GROUP BY time($interval) fill(null)",
               "rawQuery": false,
               "refId": "D",
               "resultFormat": "time_series",
@@ -711,7 +741,13 @@
               "tags": [
                 {
                   "key": "hostname",
-                  "value": "/$server/"
+                  "value": "/^$server/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ],
               "target": ""
@@ -812,7 +848,7 @@
               "interval": "",
               "measurement": "haproxy_frontend_bytes_in",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_bytes_in\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_bytes_in\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "A",
               "resultFormat": "time_series",
@@ -834,13 +870,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -862,7 +904,7 @@
               "interval": "",
               "measurement": "haproxy_frontend_bytes_out",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_bytes_out\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_bytes_out\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "B",
               "resultFormat": "time_series",
@@ -884,13 +926,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             }
@@ -980,7 +1028,7 @@
               "interval": "",
               "measurement": "haproxy_frontend_response_1xx",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_response_1xx\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_response_1xx\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "A",
               "resultFormat": "time_series",
@@ -1002,13 +1050,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -1028,7 +1082,7 @@
               ],
               "measurement": "haproxy_frontend_response_2xx",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_response_2xx\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_response_2xx\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "B",
               "resultFormat": "time_series",
@@ -1050,13 +1104,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -1076,7 +1136,7 @@
               ],
               "measurement": "haproxy_frontend_response_3xx",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_response_3xx\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_response_3xx\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "C",
               "resultFormat": "time_series",
@@ -1098,13 +1158,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -1124,7 +1190,7 @@
               ],
               "measurement": "haproxy_frontend_response_4xx",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_response_4xx\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_response_4xx\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval)",
               "rawQuery": true,
               "refId": "D",
               "resultFormat": "time_series",
@@ -1146,13 +1212,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -1172,7 +1244,7 @@
               ],
               "measurement": "haproxy_frontend_response_5xx",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s)  FROM \"haproxy_frontend_response_5xx\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s)  FROM \"haproxy_frontend_response_5xx\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "E",
               "resultFormat": "time_series",
@@ -1194,13 +1266,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -1220,7 +1298,7 @@
               ],
               "measurement": "haproxy_frontend_response_other",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_response_other\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_response_other\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "F",
               "resultFormat": "time_series",
@@ -1242,13 +1320,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             }
@@ -1343,7 +1427,7 @@
               "hide": false,
               "measurement": "haproxy_frontend_session_current",
               "policy": "default",
-              "query": "SELECT mean(\"value\") FROM \"haproxy_frontend_session_current\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT mean(\"value\") FROM \"haproxy_frontend_session_current\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter GROUP BY time($interval) fill(0)",
               "rawQuery": false,
               "refId": "A",
               "resultFormat": "time_series",
@@ -1364,12 +1448,18 @@
               "tags": [
                 {
                   "key": "hostname",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -1396,7 +1486,7 @@
               "interval": "",
               "measurement": "haproxy_frontend_session_current",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"haproxy_frontend_session_current\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"haproxy_frontend_session_current\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter GROUP BY time($interval) fill(0)",
               "rawQuery": false,
               "refId": "B",
               "resultFormat": "time_series",
@@ -1417,12 +1507,18 @@
               "tags": [
                 {
                   "key": "hostname",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -1448,7 +1544,7 @@
               "interval": "",
               "measurement": "haproxy_frontend_session_current",
               "policy": "default",
-              "query": "SELECT min(\"value\") FROM \"haproxy_frontend_session_current\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT min(\"value\") FROM \"haproxy_frontend_session_current\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter GROUP BY time($interval) fill(0)",
               "rawQuery": false,
               "refId": "C",
               "resultFormat": "time_series",
@@ -1469,12 +1565,18 @@
               "tags": [
                 {
                   "key": "hostname",
-                  "value": "/$server/"
+                  "value": "/$$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             }
@@ -1563,7 +1665,7 @@
               ],
               "measurement": "haproxy_frontend_error_requests",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_error_requests\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_error_requests\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "A",
               "resultFormat": "time_series",
@@ -1585,13 +1687,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -1611,7 +1719,7 @@
               ],
               "measurement": "haproxy_frontend_denied_requests",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_denied_requests\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_denied_requests\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "B",
               "resultFormat": "time_series",
@@ -1633,13 +1741,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ],
               "target": ""
@@ -1660,7 +1774,7 @@
               ],
               "measurement": "haproxy_frontend_denied_responses",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_denied_responses\" WHERE \"hostname\" =~ /$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_frontend_denied_responses\" WHERE \"hostname\" =~ /^$server/ AND \"frontend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "C",
               "resultFormat": "time_series",
@@ -1682,13 +1796,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "frontend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ],
               "target": ""
@@ -1790,7 +1910,7 @@
               "interval": "",
               "measurement": "haproxy_backend_bytes_in",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_bytes_in\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_bytes_in\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "A",
               "resultFormat": "time_series",
@@ -1812,13 +1932,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -1840,7 +1966,7 @@
               "interval": "",
               "measurement": "haproxy_backend_bytes_out",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_bytes_out\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_bytes_out\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval)",
               "rawQuery": true,
               "refId": "B",
               "resultFormat": "time_series",
@@ -1862,13 +1988,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             }
@@ -1958,7 +2090,7 @@
               "interval": "",
               "measurement": "haproxy_backend_response_1xx",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_response_1xx\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_response_1xx\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "A",
               "resultFormat": "time_series",
@@ -1980,13 +2112,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -2006,7 +2144,7 @@
               ],
               "measurement": "haproxy_backend_response_2xx",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_response_2xx\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_response_2xx\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "B",
               "resultFormat": "time_series",
@@ -2028,13 +2166,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -2054,7 +2198,7 @@
               ],
               "measurement": "haproxy_backend_response_3xx",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_response_3xx\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_response_3xx\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "C",
               "resultFormat": "time_series",
@@ -2076,13 +2220,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -2102,7 +2252,7 @@
               ],
               "measurement": "haproxy_backend_response_4xx",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_response_4xx\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_response_4xx\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "D",
               "resultFormat": "time_series",
@@ -2124,13 +2274,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -2150,7 +2306,7 @@
               ],
               "measurement": "haproxy_backend_response_5xx",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_response_5xx\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_response_5xx\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "E",
               "resultFormat": "time_series",
@@ -2172,13 +2328,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -2198,7 +2360,7 @@
               ],
               "measurement": "haproxy_backend_response_other",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_response_other\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_response_other\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "F",
               "resultFormat": "time_series",
@@ -2220,13 +2382,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             }
@@ -2321,7 +2489,7 @@
               "hide": false,
               "measurement": "haproxy_backend_session_current",
               "policy": "default",
-              "query": "SELECT mean(\"value\") FROM \"haproxy_backend_session_current\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT mean(\"value\") FROM \"haproxy_backend_session_current\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter GROUP BY time($interval) fill(0)",
               "rawQuery": false,
               "refId": "A",
               "resultFormat": "time_series",
@@ -2342,12 +2510,18 @@
               "tags": [
                 {
                   "key": "hostname",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -2374,7 +2548,7 @@
               "interval": "",
               "measurement": "haproxy_backend_session_current",
               "policy": "default",
-              "query": "SELECT max(\"value\") FROM \"haproxy_backend_session_current\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT max(\"value\") FROM \"haproxy_backend_session_current\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter GROUP BY time($interval) fill(0)",
               "rawQuery": false,
               "refId": "B",
               "resultFormat": "time_series",
@@ -2395,12 +2569,18 @@
               "tags": [
                 {
                   "key": "hostname",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             },
@@ -2426,7 +2606,7 @@
               "interval": "",
               "measurement": "haproxy_backend_session_current",
               "policy": "default",
-              "query": "SELECT min(\"value\") FROM \"haproxy_backend_session_current\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter GROUP BY time($interval) fill(0)",
+              "query": "SELECT min(\"value\") FROM \"haproxy_backend_session_current\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter GROUP BY time($interval) fill(0)",
               "rawQuery": false,
               "refId": "C",
               "resultFormat": "time_series",
@@ -2447,12 +2627,18 @@
               "tags": [
                 {
                   "key": "hostname",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ]
             }
@@ -2539,7 +2725,7 @@
               ],
               "measurement": "haproxy_backend_error_connection",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_error_connection\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_error_connection\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "A",
               "resultFormat": "time_series",
@@ -2561,13 +2747,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ],
               "target": ""
@@ -2586,7 +2778,7 @@
               ],
               "measurement": "haproxy_backend_error_responses",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_error_responses\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_error_responses\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "B",
               "resultFormat": "time_series",
@@ -2608,13 +2800,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ],
               "target": ""
@@ -2636,7 +2834,7 @@
               "interval": "",
               "measurement": "haproxy_backend_denied_requests",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_denied_requests\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_denied_requests\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "C",
               "resultFormat": "time_series",
@@ -2658,13 +2856,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ],
               "target": ""
@@ -2686,7 +2890,7 @@
               "interval": "",
               "measurement": "haproxy_backend_denied_responses",
               "policy": "default",
-              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_denied_responses\" WHERE \"hostname\" =~ /$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
+              "query": "SELECT derivative(first(value),1s) FROM \"haproxy_backend_denied_responses\" WHERE \"hostname\" =~ /^$server/ AND \"backend\" =~ /$service/ AND $timeFilter AND \"environment_label\" =~ /^$environment$/GROUP BY time($interval) fill(0)",
               "rawQuery": true,
               "refId": "D",
               "resultFormat": "time_series",
@@ -2708,13 +2912,19 @@
                 {
                   "key": "hostname",
                   "operator": "=~",
-                  "value": "/$server/"
+                  "value": "/^$server/"
                 },
                 {
                   "condition": "AND",
                   "key": "backend",
                   "operator": "=~",
                   "value": "/$service/"
+                },
+                {
+                  "condition": "AND",
+                  "key": "environment_label",
+                  "operator": "=~",
+                  "value": "/^$environment$/"
                 }
               ],
               "target": ""
@@ -2844,5 +3054,5 @@
   },
   "timezone": "browser",
   "title": "HAProxy",
-  "version": 6
+  "version": 7
 }
diff --git a/haproxy/files/haproxy.cfg b/haproxy/files/haproxy.cfg
index 58c1b1e..7aae743 100644
--- a/haproxy/files/haproxy.cfg
+++ b/haproxy/files/haproxy.cfg
@@ -63,14 +63,14 @@
 
 listen {{ listen_name }}
   {%- for bind in listen.binds %}
-  bind {{ bind.address }}:{{ bind.port }} {% if bind.get('ssl', {}).enabled|default(False) %}ssl crt {{ bind.ssl.pem_file }}{% endif %}
+  bind {{ bind.address }}:{{ bind.port }} {% if bind.get('ssl', {}).enabled|default(False) %}{% if bind.ssl.pem_file is defined %}ssl crt {{ bind.ssl.pem_file }}{% else %}crt /etc/haproxy/ssl/{{ listen_name }}{% endif %}{% endif %}
   {%- endfor %}
   {%- if listen.get('type', None) == 'http' %}
   mode http
-  balance  roundrobin
+  balance {{ listen.get('balance', 'roundrobin') }}
   option  httplog
   {%- elif listen.get('type', None) == 'rabbitmq' %}
-  balance roundrobin
+  balance {{ listen.get('balance', 'roundrobin') }}
   mode tcp
   option tcpka
   timeout client 300s
@@ -85,6 +85,16 @@
   timeout client  300s
   timeout server  300s
   option mysql-check user haproxy
+  {%- elif listen.get('type', None) == 'pgsql' %}
+  balance leastconn
+  mode tcp
+  option httpchk
+  option tcplog
+  option clitcpka
+  option srvtcpka
+  timeout client  28801s
+  timeout server  28801s
+  option pgsql-check user postgres
   {%- elif listen.get('type', None) == 'horizon' %}
   balance  source
   capture  cookie vgnvisitor= len 32
@@ -97,7 +107,7 @@
   rspidel ^Set-cookie:\ IP=
   {%- elif listen.get('type', None) == 'general-service' %}
   mode http
-  balance  roundrobin
+  balance {{ listen.get('balance', 'roundrobin') }}
   option  httplog
   {%- elif listen.get('type', None) == 'openstack-service' %}
   option  httpchk
@@ -115,10 +125,10 @@
   stats auth {{ listen.user }}:{{ listen.password }}
   {%- elif listen.get('type', None) == 'contrail-api' %}
   option nolinger
-  balance roundrobin
+  balance {{ listen.get('balance', 'roundrobin') }}
   {%- elif listen.get('type', None) == 'contrail-analytics' %}
   option nolinger
-  balance roundrobin
+  balance {{ listen.get('balance', 'roundrobin') }}
   option tcp-check
   tcp-check connect port 6379
   default-server error-limit 1 on-error mark-down
@@ -157,6 +167,16 @@
   {%- for option in listen.get('options', []) %}
   option {{ option }}
   {%- endfor %}
+  {%- for type, checks in listen.get('health-check', {}).iteritems() %}
+  {%- if checks.get('enabled', True) %}
+  {%- if type == 'http' and 'httpchk' not in listen.get('options', []) %}
+  option httpchk
+  {%- endif %}
+  {%- for option in checks.get('options', []) %}
+  {{ type }}-check {{ option }}
+  {%- endfor %}
+  {%- endif %}
+  {%- endfor %}
   {%- for stick in listen.get('sticks', []) %}
   {{ stick }}
   {%- endfor %}
@@ -188,7 +208,7 @@
 
 backend {{ listen_name }}-backend
   {%- if listen.get('type', None) == 'http' %}
-  balance roundrobin
+  balance {{ listen.get('balance', 'roundrobin') }}
   {%- endif %}
   {%- for server in listen.get('servers', []) %}
   server {{ server.get('name', server.host) }} {{ server.host }}:{{ server.port }} {{ server.get('params', '') }}
@@ -196,7 +216,7 @@
 {%- for acl in listen.get('acls', []) %}
 
 backend {{ acl.name }}-backend
-  balance     roundrobin
+  balance {{ acl.get('balance', 'roundrobin') }}
   {%- for server in acl.get('servers', []) %}
   server {{ server.get('name', server.host) }} {{ server.host }}:{{ server.port }} {{ server.get('params', '') }}
   {%- endfor %}
diff --git a/haproxy/files/ssl_all.pem b/haproxy/files/ssl_all.pem
new file mode 100644
index 0000000..748f351
--- /dev/null
+++ b/haproxy/files/ssl_all.pem
@@ -0,0 +1,6 @@
+{#-
+  vim: syntax=jinja
+-#}
+{{ key }}
+{{ cert }}
+{% if chain %}{{ chain }}{% endif %}
diff --git a/haproxy/meta/grafana.yml b/haproxy/meta/grafana.yml
index d5b90c1..5f9daca 100644
--- a/haproxy/meta/grafana.yml
+++ b/haproxy/meta/grafana.yml
@@ -2,3 +2,18 @@
   haproxy:
     format: json
     template: haproxy/files/grafana_dashboards/haproxy_influxdb.json
+  main:
+    row:
+      ost-middleware:
+        title: Middleware
+        panel:
+          haproxy:
+            title: HAProxy
+            links:
+            - dashboard: HAProxy
+              title: HAProxy
+              type: dashboard
+            target:
+              cluster_status:
+                rawQuery: true
+                query: SELECT last(value) FROM cluster_status WHERE cluster_name = 'haproxy-openstack' AND environment_label = '$environment' AND $timeFilter GROUP BY time($interval) fill(null)
diff --git a/haproxy/proxy.sls b/haproxy/proxy.sls
index 427a266..d5e65cd 100644
--- a/haproxy/proxy.sls
+++ b/haproxy/proxy.sls
@@ -27,10 +27,16 @@
   - require:
     - pkg: haproxy_packages
 
+{%- if grains.get('virtual_subtype', None) not in ['Docker', 'LXC'] %}
+
 net.ipv4.ip_nonlocal_bind:
   sysctl.present:
     - value: 1
 
+{% endif %}
+
+{% if not grains.get('noservices', False) %}
+
 haproxy_service:
   service.running:
   - name: {{ proxy.service }}
@@ -39,4 +45,36 @@
     - file: /etc/haproxy/haproxy.cfg
     - file: /etc/default/haproxy
 
+{% endif %}
+
+{%- for listen_name, listen in proxy.get('listen', {}).iteritems() %}
+  {%- if listen.get('enabled', True) %}
+    {%- for bind in listen.binds %}
+      {% if bind.get('ssl', {}).enabled|default(False) and bind.ssl.key is defined %}
+        {%- set pem_file = bind.ssl.get('pem_file', '/etc/haproxy/ssl/%s/%s-all.pem'|format(listen_name, loop.index)) %}
+
+{{ pem_file }}:
+  file.managed:
+    - template: jinja
+    - source: salt://haproxy/files/ssl_all.pem
+    - user: root
+    - group: haproxy
+    - mode: 640
+    - makedirs: true
+    - defaults:
+        key: {{ bind.ssl.key|yaml }}
+        cert: {{ bind.ssl.cert|yaml }}
+        chain: {{ bind.ssl.get('chain', '')|yaml }}
+    - require:
+      - file: haproxy_ssl
+    {% if not grains.get('noservices', False) %}
+    - watch_in:
+      - service: haproxy_service
+    {% endif %}
+
+      {%- endif %}
+    {%- endfor %}
+  {%- endif %}
+{%- endfor %}
+
 {%- endif %}
diff --git a/metadata.yml b/metadata.yml
index 21781fb..48c699e 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,3 +1,3 @@
 name: "haproxy"
 version: "0.2"
-source: "https://github.com/tcpcloud/salt-formula-haproxy"
+source: "https://github.com/salt-formulas/salt-formula-haproxy"