浏览代码

Support working directory for container and file credential hooks.

Dan Helfman 3 月之前
父节点
当前提交
e02a0e6322

+ 3 - 1
borgmatic/hooks/credential/container.py

@@ -29,7 +29,9 @@ def load_credential(hook_config, config, credential_parameters):
     try:
         with open(
             os.path.join(
-                (hook_config or {}).get('secrets_directory', DEFAULT_SECRETS_DIRECTORY), secret_name
+                config.get('working_directory', ''),
+                (hook_config or {}).get('secrets_directory', DEFAULT_SECRETS_DIRECTORY),
+                secret_name,
             )
         ) as secret_file:
             return secret_file.read().rstrip(os.linesep)

+ 3 - 1
borgmatic/hooks/credential/file.py

@@ -18,7 +18,9 @@ def load_credential(hook_config, config, credential_parameters):
         raise ValueError(f'Cannot load invalid credential: "{' '.join(credential_parameters)}"')
 
     try:
-        with open(credential_path) as credential_file:
+        with open(
+            os.path.join(config.get('working_directory', ''), credential_path)
+        ) as credential_file:
             return credential_file.read().rstrip(os.linesep)
     except (FileNotFoundError, OSError) as error:
         logger.warning(error)

+ 17 - 0
tests/unit/hooks/credential/test_container.py

@@ -49,6 +49,23 @@ def test_load_credential_with_custom_secrets_directory_looks_there_for_secret_fi
     )
 
 
+def test_load_credential_with_custom_secrets_directory_prefixes_it_with_working_directory():
+    config = {'container': {'secrets_directory': 'secrets'}, 'working_directory': '/working'}
+    credential_stream = io.StringIO('password')
+    credential_stream.name = '/working/secrets/mysecret'
+    builtins = flexmock(sys.modules['builtins'])
+    builtins.should_receive('open').with_args('/working/secrets/mysecret').and_return(
+        credential_stream
+    )
+
+    assert (
+        module.load_credential(
+            hook_config=config['container'], config=config, credential_parameters=('mysecret',)
+        )
+        == 'password'
+    )
+
+
 def test_load_credential_with_file_not_found_error_raises():
     builtins = flexmock(sys.modules['builtins'])
     builtins.should_receive('open').with_args('/run/secrets/mysecret').and_raise(FileNotFoundError)

+ 18 - 0
tests/unit/hooks/credential/test_file.py

@@ -38,6 +38,24 @@ def test_load_credential_reads_named_credential_from_file():
     )
 
 
+def test_load_credential_reads_named_credential_from_file_using_working_directory():
+    credential_stream = io.StringIO('password')
+    credential_stream.name = '/working/credentials/mycredential'
+    builtins = flexmock(sys.modules['builtins'])
+    builtins.should_receive('open').with_args('/working/credentials/mycredential').and_return(
+        credential_stream
+    )
+
+    assert (
+        module.load_credential(
+            hook_config={},
+            config={'working_directory': '/working'},
+            credential_parameters=('credentials/mycredential',),
+        )
+        == 'password'
+    )
+
+
 def test_load_credential_with_file_not_found_error_raises():
     builtins = flexmock(sys.modules['builtins'])
     builtins.should_receive('open').with_args('/credentials/mycredential').and_raise(