Skip to content
This repository was archived by the owner on Dec 13, 2018. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ Settings in this part is immutable, you have to redeploy HAProxy service to make

|Environment Variable|Default|Description|
|:-----:|:-----:|:----------|
|ADDITIONAL_BACKENDS| |list of additional backends to balance. The format is `backend name, FORCE_SSL(True|False), server name, host:port, options`|
|ADDITIONAL_SERVICES| |list of additional services to balance (es: `prj1:web,prj2:sql`). Discovery will be based on `com.docker.compose.[project|service]` container labels. This environment variable only works on compose v2, and the referenced services must be on a network resolvable and accessible to this containers.|
|BALANCE|roundrobin|load balancing algorithm to use. Possible values include: `roundrobin`, `static-rr`, `source`, `leastconn`. See:[HAProxy:balance](https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#4-balance)|
|CA_CERT_FILE| |the path of a ca-cert file. This allows you to mount your ca-cert file directly from a volume instead of from envvar. If set, `CA_CERT` envvar will be ignored. Possible value: `/cacerts/cert0.pem`|
Expand All @@ -182,6 +183,7 @@ Settings in this part is immutable, you have to redeploy HAProxy service to make
|EXTRA_GLOBAL_SETTINGS| |comma-separated string of extra settings, and each part will be appended to GLOBAL section in the configuration file. To escape comma, use `\,`. Possible value: `tune.ssl.cachesize 20000, tune.ssl.default-dh-param 2048`|
|EXTRA_ROUTE_SETTINGS| |a string which is append to the each backend route after the health check, can be over written in the linked services. Possible value: "send-proxy"|
|EXTRA_SSL_CERTS| |list of extra certificate names separated by comma, eg. `CERT1, CERT2, CERT3`. You also need to specify each certificate as separate env variables like so: `CERT1="<cert-body1>"`, `CERT2="<cert-body2>"`, `CERT3="<cert-body3>"`|
|FORCE_DEFAULT_BACKEND| True | set the default_service as a default backend. This is useful when you have more than one backend and you don't want your default_service as a default backend
|HEALTH_CHECK|check|set health check on each backend route, possible value: "check inter 2000 rise 2 fall 3". See:[HAProxy:check](https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#5.2-check)|
|HTTP_BASIC_AUTH| |a comma-separated list of credentials(`<user>:<pass>`) for HTTP basic auth, which applies to all the backend routes. To escape comma, use `\,`. *Attention:* DO NOT rely on this for authentication in production|
|MAXCONN|4096|sets the maximum per-process number of concurrent connections.|
Expand Down Expand Up @@ -477,4 +479,4 @@ Legacy links:
In most cases, `dockercloud/haproxy` will configure itself automatically when the linked services change, you don't need to reload it manually. But for some reason, if you have to do so, here is how:

* `docker exec <haproxy_id> /reload.sh`, if you are on the node where dockercloud/haproxy deploys
* `docker-cloud exec <haproxy_uuid> /reload.sh`, if you use docker-cloud cli
* `docker-cloud exec <haproxy_uuid> /reload.sh`, if you use docker-cloud cli
16 changes: 16 additions & 0 deletions haproxy/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,23 @@ def parse_extra_frontend_settings(envvars):
settings_dict[port] = settings
return settings_dict

def parse_additional_backend_settings(envvars):
settings_dict = {}
if isinstance(envvars, os._Environ) or isinstance(envvars, dict):
frontend_settings_pattern = re.compile(r"^ADDITIONAL_BACKEND_(\w{1,9})$")
for k, v in envvars.iteritems():
match = frontend_settings_pattern.match(k)
if match:
server = match.group(1)
settings = [x.strip().replace("\,", ",") for x in re.split(r'(?<!\\),', v.strip())]
if server in settings_dict:
settings_dict[server].extend(settings)
else:
settings_dict[server] = settings
return settings_dict

# envvar
ADDITIONAL_BACKENDS = parse_additional_backend_settings(os.environ)
ADDITIONAL_SERVICES = os.getenv("ADDITIONAL_SERVICES")
API_AUTH = os.getenv("DOCKERCLOUD_AUTH")
BALANCE = os.getenv("BALANCE", "roundrobin")
Expand All @@ -44,6 +59,7 @@ def parse_extra_frontend_settings(envvars):
EXTRA_GLOBAL_SETTINGS = os.getenv("EXTRA_GLOBAL_SETTINGS")
EXTRA_SSL_CERT = os.getenv("EXTRA_SSL_CERTS")
EXTRA_ROUTE_SETTINGS=os.getenv("EXTRA_ROUTE_SETTINGS", "")
FORCE_DEFAULT_BACKEND = os.getenv("FORCE_DEFAULT_BACKEND", "True")
HAPROXY_CONTAINER_URI = os.getenv("DOCKERCLOUD_CONTAINER_API_URI")
HAPROXY_SERVICE_URI = os.getenv("DOCKERCLOUD_SERVICE_API_URI")
HEALTH_CHECK = os.getenv("HEALTH_CHECK", "check inter 2000 rise 2 fall 3")
Expand Down
10 changes: 10 additions & 0 deletions haproxy/haproxycfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def update(self):
cfg_dict.update(self._config_tcp_sections())
cfg_dict.update(self._config_frontend_sections())
cfg_dict.update(self._config_backend_sections())
cfg_dict.update(self._config_adittional_backends_sections())

cfg = prettify(cfg_dict)
self._update_haproxy(cfg)
Expand Down Expand Up @@ -329,3 +330,12 @@ def _config_backend_sections(self):
else:
cfg["backend default_service"] = backend
return cfg

def _config_adittional_backends_sections(self):
cfg = OrderedDict()

if ADDITIONAL_BACKENDS:
for key in ADDITIONAL_BACKENDS:
cfg["backend %s" % key] = ADDITIONAL_BACKENDS[key]

return cfg
2 changes: 1 addition & 1 deletion haproxy/helper/backend_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def get_backend_section(details, routes, vhosts, service_alias, routes_added):
route_setting = " ".join([route_health_check, extra_route_settings]).strip()
backend_routes = get_backend_routes(route_setting, is_sticky, routes, routes_added, service_alias)
backend.extend(backend_routes)

return backend


Expand All @@ -44,7 +45,6 @@ def get_backend_routes(route_setting, is_sticky, routes, routes_added, service_a

return sorted(backend_routes)


def get_route_health_check(details, service_alias, default_health_check):
health_check = get_service_attribute(details, "health_check", service_alias)
health_check = health_check if health_check else default_health_check
Expand Down
10 changes: 7 additions & 3 deletions haproxy/helper/frontend_helper.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from collections import OrderedDict

from haproxy.config import EXTRA_BIND_SETTINGS, EXTRA_FRONTEND_SETTINGS, MONITOR_URI, MONITOR_PORT, MAXCONN, \
SKIP_FORWARDED_PROTO
SKIP_FORWARDED_PROTO, FORCE_DEFAULT_BACKEND


def check_require_default_route(routes, routes_added):
Expand Down Expand Up @@ -152,7 +152,9 @@ def config_default_frontend(ssl_bind_string):
if "80" in EXTRA_FRONTEND_SETTINGS:
frontend.extend(EXTRA_FRONTEND_SETTINGS["80"])

frontend.append("default_backend default_service")
if "True" in FORCE_DEFAULT_BACKEND:
frontend.append("default_backend default_service")

cfg["frontend default_port_80"] = frontend

if ssl_bind_string:
Expand All @@ -171,7 +173,9 @@ def config_default_frontend(ssl_bind_string):
if "443" in EXTRA_FRONTEND_SETTINGS:
ssl_frontend.extend(EXTRA_FRONTEND_SETTINGS["443"])

ssl_frontend.append("default_backend default_service")
if "True" in FORCE_DEFAULT_BACKEND:
ssl_frontend.append("default_backend default_service")

cfg["frontend default_port_443"] = ssl_frontend

return cfg, monitor_uri_configured
Expand Down