diff --git a/README.md b/README.md index 09373a8..7417dc7 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ Important: easyhaproxy needs to be in the same network of the containers or othe | com.byjg.easyhaproxy.host.[definition] | What is the host that the HAProxy will listen to. | | com.byjg.easyhaproxy.redirect.[definition] | (Optional) Host redirects from connections in the port defined above. | | com.byjg.easyhaproxy.sslcert.[definition] | (Optional) Cert PEM Base64 encoded. | - +| com.byjg.easyhaproxy.health-check.[definition] | (Optional) `ssl`, enable health check via SSL in `mode tcp` (Defaults to "empty") | Note: if you are deploying a stack set labels at the `deploy` level: @@ -135,11 +135,14 @@ Used to pass on SSL-termination to a backend: docker run \ -l com.byjg.easyhaproxy.defintions=tcp-service \ -l com.byjg.easyhaproxy.mode.tcp-service=tcp \ + -l com.byjg.easyhaproxy.health-check.tcp-service=ssl \ -l com.byjg.easyhaproxy.port.tcp-service=443 .... \ some/tcp-service ``` + - enable health-check via SSL on the backend with the optional `health-check` label + ### Redirect Example: ```bash diff --git a/easymapping/__init__.py b/easymapping/__init__.py index d0d0e69..a26b99f 100644 --- a/easymapping/__init__.py +++ b/easymapping/__init__.py @@ -101,6 +101,7 @@ class HaproxyConfigGenerator: if key not in easymapping: easymapping[key] = { "mode": mode, + "health-check": "", "port": port, "hosts": dict(), "redirect": dict(), @@ -112,6 +113,11 @@ class HaproxyConfigGenerator: "80" ) + easymapping[key]["health-check"] = self.label.get( + self.label.create(["health-check", definition]), + "" + ) + easymapping[key]["hosts"][d[host_label]] = "{}:{}".format(container, ct_port) # handle SSL diff --git a/templates/haproxy.cfg.j2 b/templates/haproxy.cfg.j2 index 6b502d6..192bbd4 100644 --- a/templates/haproxy.cfg.j2 +++ b/templates/haproxy.cfg.j2 @@ -60,8 +60,8 @@ backend srv_{{ host }} http-request add-header X-Forwarded-Proto https if { ssl_fc } {% elif mode == "tcp" %} option tcp-check - tcp-check connect + tcp-check connect{{ " ssl" if o["health-check"] == "ssl" }} {% endif %} - server srv {{ o["hosts"][k] }} check weight 1 + server srv {{ o["hosts"][k] }} check weight 1{{ " verify none" if o["health-check"] == "ssl" }} {% endfor %} {% endfor %} diff --git a/tests/fixtures/services-tcp b/tests/fixtures/services-tcp index 8520b59..64bb7a6 100644 --- a/tests/fixtures/services-tcp +++ b/tests/fixtures/services-tcp @@ -1,2 +1,2 @@ -test_agent={"com.byjg.easyhaproxy.definitions":"agent","com.byjg.easyhaproxy.host.agent":"agent.quantum.local","com.byjg.easyhaproxy.localport.agent":"9001","com.byjg.easyhaproxy.mode.agent":"tcp","com.byjg.easyhaproxy.port.agent":"31339","com.docker.stack.image":"portainer/agent:1.5.1","com.docker.stack.namespace":"test","com.planetary-quantum":"monitoring"} +test_agent={"com.byjg.easyhaproxy.definitions":"agent","com.byjg.easyhaproxy.host.agent":"agent.quantum.local","com.byjg.easyhaproxy.localport.agent":"9001","com.byjg.easyhaproxy.mode.agent":"tcp","com.byjg.easyhaproxy.port.agent":"31339","com.docker.stack.image":"portainer/agent:1.5.1","com.docker.stack.namespace":"test", "com.byjg.easyhaproxy.health-check.agent":"ssl"} test_proxy={"com.docker.stack.image":"byjg/easy-haproxy:local","com.docker.stack.namespace":"test"} diff --git a/tests/test_parser.py b/tests/test_parser.py index edf0357..0851833 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -59,12 +59,50 @@ def test_parser_static(): assert "redirect prefix http://host1.com.br code 301 if { hdr(host) -i www.host1.com.br }" in haproxy_config # assert that we found the services - assert "frontend http_in_80_1" in haproxy_config - assert "bind *:80" - assert "frontend http_in_443_2" in haproxy_config - assert "bind *:443" - assert "frontend http_in_8080_3" in haproxy_config - assert "bind :*8080" + frontend_http_cfg = "frontend http_in_80_1\n" + frontend_http_cfg += " bind *:80" + assert frontend_http_cfg in haproxy_config - # verify ssl config - assert "frontend http_in_443_2\n bind *:443 ssl crt BASE64_PEM_CERTIFICATE" in haproxy_config + frontend_https_cfg = "frontend http_in_443_2\n" + frontend_https_cfg += " bind *:443" + assert frontend_https_cfg in haproxy_config + + # print(haproxy_config) + frontend_http8080_cfg = "frontend http_in_8080_3\n" + frontend_http8080_cfg += " bind *:8080" + assert frontend_http8080_cfg in haproxy_config + + + # verify ssl config with certificate + frontend_ssl_cfg = "frontend http_in_443_2\n" + frontend_ssl_cfg += " bind *:443 ssl crt BASE64_PEM_CERTIFICATE" + assert frontend_ssl_cfg in haproxy_config + + +def test_parser_tcp(): + lineList = load_fixture("services-tcp") + + result = { + "customerrors": False + } + + cfg = easymapping.HaproxyConfigGenerator(result) + haproxy_config = cfg.generate(lineList) + # print(haproxy_config) + + frontend_cfg = "frontend tcp_in_31339_1\n" + frontend_cfg += " bind *:31339\n" + frontend_cfg += " mode tcp\n" + frontend_cfg += " option tcplog\n" + frontend_cfg += " log global\n" + frontend_cfg += " default_backend srv_agent_quantum_local_31339_1\n\n" + assert frontend_cfg in haproxy_config + + backend_cfg = "backend srv_agent_quantum_local_31339_1\n" + backend_cfg += " balance roundrobin\n" + backend_cfg += " mode tcp\n" + backend_cfg += " option tcp-check\n" + backend_cfg += " tcp-check connect ssl\n" + backend_cfg += " server srv test_agent:9001 check weight 1 verify none" + + assert backend_cfg in haproxy_config