Skip to content
This repository has been archived by the owner on Dec 4, 2024. It is now read-only.

Support providing MLB templates via environment variables rather than… #492

Merged
30 changes: 22 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
24 changes: 16 additions & 8 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to add a test to tests/test_marathon_lb.py? You should be able to do something like

os.environ["key"] = "val"

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 = '''\
Expand Down
32 changes: 32 additions & 0 deletions tests/test_marathon_lb.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down