diff --git a/README.md b/README.md index dcc3f3ab..b1374d63 100644 --- a/README.md +++ b/README.md @@ -197,14 +197,28 @@ of labels. ### Templates -Marathon-lb searches for configuration files in the `templates/` -directory. The `templates/` directory is located in a relative -path from where the script is run. Some templates can also be -[overridden _per app service port_](#overridable-templates). You may add your -own templates to the Docker image, or provide them at startup. - -See [the configuration doc for the full list](Longhelp.md#templates) -of templates. +Marathon-lb global templates (as listed in the [Longhelp](Longhelp.md#templates)) can be overwritten in two ways: +-By creating an environment variable in the marathon-lb container +-By placing configuration files in the `templates/` directory (relative to where the script is run from) + +For example, to replace `HAPROXY_HTTPS_FRONTEND_HEAD` with this content: + +``` +frontend new_frontend_label + bind *:443 ssl crt /etc/ssl/cert.pem + mode http +``` + +Then this environment variable could be added to the Marathon-LB configuration: +``` +"HAPROXY_HTTPS_FRONTEND_HEAD": "\\nfrontend new_frontend_label\\n bind *:443 ssl {sslCerts}\\n mode http" +``` + +Alternately, a file called`HAPROXY_HTTPS_FRONTEND_HEAD` could be placed in `templates/` directory through the use of an artifact URI. + +Additionally, some templates can also be [overridden _per app service port_](#overridable-templates). You may add your own templates to the Docker image, or provide them at startup. + +See [the configuration doc for the full list](Longhelp.md#templates) of templates. #### Overridable Templates diff --git a/config.py b/config.py index 9f74abf3..5f291128 100644 --- a/config.py +++ b/config.py @@ -770,17 +770,25 @@ def __init__(self, directory='templates'): self.__load_templates() def __load_templates(self): - '''Loads template files if they exist, othwerwise it sets defaults''' + '''Look in environment variables for templates. If not set in env, + load template files if they exist. Othwerwise it sets defaults''' for template in self.t: name = self.t[template].full_name - try: - filename = os.path.join(self.__template_directory, name) - with open(filename) as f: - logger.info('overriding %s from %s', name, filename) - self.t[template].value = f.read() - except IOError: - logger.debug("setting default value for %s", name) + if os.environ.get(name): + logger.info('overriding %s from environment variable', name) + env_template_val = os.environ.get(name) + + # Handle escaped endlines + self.t[template].value = env_template_val.replace("\\n", "\n") + else: + try: + filename = os.path.join(self.__template_directory, name) + with open(filename) as f: + logger.info('overriding %s from %s', name, filename) + self.t[template].value = f.read() + except IOError: + logger.debug("setting default value for %s", name) def get_descriptions(self): descriptions = '''\ diff --git a/tests/test_marathon_lb.py b/tests/test_marathon_lb.py index 85d0a5d1..fc02c41e 100644 --- a/tests/test_marathon_lb.py +++ b/tests/test_marathon_lb.py @@ -98,6 +98,38 @@ def test_config_no_apps(self): bind *:9091 mode http +frontend marathon_https_in + bind *:443 ssl crt /etc/ssl/cert.pem + mode http +''' + print("actual config:\n") + print(config) + self.assertMultiLineEqual(config, expected) + + def test_config_env_template(self): + apps = dict() + groups = ['external'] + bind_http_https = True + ssl_certs = "" + os.environ["HAPROXY_HTTP_FRONTEND_HEAD"] = ''' +frontend changed_frontend + bind *:80 + mode http +''' + templater = marathon_lb.ConfigTemplater() + del os.environ["HAPROXY_HTTP_FRONTEND_HEAD"] + + config = marathon_lb.config(apps, groups, bind_http_https, + ssl_certs, templater) + expected = self.base_config + ''' +frontend changed_frontend + bind *:80 + mode http + +frontend marathon_http_appid_in + bind *:9091 + mode http + frontend marathon_https_in bind *:443 ssl crt /etc/ssl/cert.pem mode http