Fix escaped environment variable in configuration (#546).
Reviewed-on: https://projects.torsion.org/borgmatic-collective/borgmatic/pulls/549
This commit is contained in:
commit
c664c6b17b
2 changed files with 23 additions and 3 deletions
|
@ -1,7 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
_VARIABLE_PATTERN = re.compile(r'(?<!\\)\$\{(?P<name>[A-Za-z0-9_]+)((:?-)(?P<default>[^}]+))?\}')
|
_VARIABLE_PATTERN = re.compile(r'(?P<escape>\\)?(?P<variable>\$\{(?P<name>[A-Za-z0-9_]+)((:?-)(?P<default>[^}]+))?\})')
|
||||||
|
|
||||||
|
|
||||||
def _resolve_string(matcher):
|
def _resolve_string(matcher):
|
||||||
|
@ -9,10 +9,14 @@ def _resolve_string(matcher):
|
||||||
Get the value from environment given a matcher containing a name and an optional default value.
|
Get the value from environment given a matcher containing a name and an optional default value.
|
||||||
If the variable is not defined in environment and no default value is provided, an Error is raised.
|
If the variable is not defined in environment and no default value is provided, an Error is raised.
|
||||||
'''
|
'''
|
||||||
name, default = matcher.group("name"), matcher.group("default")
|
if matcher.group('escape') is not None:
|
||||||
|
# in case of escaped envvar, unescape it
|
||||||
|
return matcher.group('variable')
|
||||||
|
# resolve the env var
|
||||||
|
name, default = matcher.group('name'), matcher.group('default')
|
||||||
out = os.getenv(name, default=default)
|
out = os.getenv(name, default=default)
|
||||||
if out is None:
|
if out is None:
|
||||||
raise ValueError("Cannot find variable ${name} in environment".format(name=name))
|
raise ValueError('Cannot find variable ${name} in environment'.format(name=name))
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,20 @@ def test_env_braces(monkeypatch):
|
||||||
module.resolve_env_variables(config)
|
module.resolve_env_variables(config)
|
||||||
assert config == {'key': 'Hello foo'}
|
assert config == {'key': 'Hello foo'}
|
||||||
|
|
||||||
|
def test_env_multi(monkeypatch):
|
||||||
|
monkeypatch.setenv('MY_CUSTOM_VALUE', 'foo')
|
||||||
|
monkeypatch.setenv('MY_CUSTOM_VALUE2', 'bar')
|
||||||
|
config = {'key': 'Hello ${MY_CUSTOM_VALUE}${MY_CUSTOM_VALUE2}'}
|
||||||
|
module.resolve_env_variables(config)
|
||||||
|
assert config == {'key': 'Hello foobar'}
|
||||||
|
|
||||||
|
def test_env_escape(monkeypatch):
|
||||||
|
monkeypatch.setenv('MY_CUSTOM_VALUE', 'foo')
|
||||||
|
monkeypatch.setenv('MY_CUSTOM_VALUE2', 'bar')
|
||||||
|
config = {'key': r'Hello ${MY_CUSTOM_VALUE} \${MY_CUSTOM_VALUE}'}
|
||||||
|
module.resolve_env_variables(config)
|
||||||
|
assert config == {'key': r'Hello foo ${MY_CUSTOM_VALUE}'}
|
||||||
|
|
||||||
|
|
||||||
def test_env_default_value(monkeypatch):
|
def test_env_default_value(monkeypatch):
|
||||||
monkeypatch.delenv('MY_CUSTOM_VALUE', raising=False)
|
monkeypatch.delenv('MY_CUSTOM_VALUE', raising=False)
|
||||||
|
@ -41,6 +55,7 @@ def test_env_full(monkeypatch):
|
||||||
'anotherdict': {
|
'anotherdict': {
|
||||||
'key': 'My ${MY_CUSTOM_VALUE} here',
|
'key': 'My ${MY_CUSTOM_VALUE} here',
|
||||||
'other': '${MY_CUSTOM_VALUE}',
|
'other': '${MY_CUSTOM_VALUE}',
|
||||||
|
'escaped': r'\${MY_CUSTOM_VALUE}',
|
||||||
'list': [
|
'list': [
|
||||||
'/home/${MY_CUSTOM_VALUE}/.local',
|
'/home/${MY_CUSTOM_VALUE}/.local',
|
||||||
'/var/log/',
|
'/var/log/',
|
||||||
|
@ -62,6 +77,7 @@ def test_env_full(monkeypatch):
|
||||||
'anotherdict': {
|
'anotherdict': {
|
||||||
'key': 'My foo here',
|
'key': 'My foo here',
|
||||||
'other': 'foo',
|
'other': 'foo',
|
||||||
|
'escaped': '${MY_CUSTOM_VALUE}',
|
||||||
'list': ['/home/foo/.local', '/var/log/', '/home/bar/.config'],
|
'list': ['/home/foo/.local', '/var/log/', '/home/bar/.config'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue