rename utils.py to config.py

This commit is contained in:
Florian Apolloner
2025-09-15 20:02:31 +02:00
parent 97815bb498
commit 0d190016d3
8 changed files with 133 additions and 127 deletions
+9 -8
View File
@@ -12,7 +12,8 @@ from borgmatic.execute import (
execute_command_and_capture_output,
execute_command_with_processes,
)
from borgmatic.hooks.data_source import dump, utils
from borgmatic.hooks.data_source import config as ds_config
from borgmatic.hooks.data_source import dump
logger = logging.getLogger(__name__)
@@ -122,7 +123,7 @@ def database_names_to_dump(database, config, username, password, environment, dr
)
extra_options, defaults_extra_filename = parse_extra_options(database.get('list_options'))
password_transport = database.get('password_transport', 'pipe')
hostname = utils.resolve_database_option('hostname', database)
hostname = ds_config.resolve_database_option('hostname', database)
show_command = (
mariadb_show_command
+ (
@@ -194,7 +195,7 @@ def execute_dump_command(
)
extra_options, defaults_extra_filename = parse_extra_options(database.get('options'))
password_transport = database.get('password_transport', 'pipe')
hostname = utils.resolve_database_option('hostname', database)
hostname = ds_config.resolve_database_option('hostname', database)
dump_command = (
mariadb_dump_command
+ (
@@ -417,17 +418,17 @@ def restore_data_source_dump(
subprocess.Popen) to produce output to consume.
'''
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
hostname = utils.resolve_database_option(
hostname = ds_config.resolve_database_option(
'hostname', data_source, connection_params, restore=True
)
port = utils.resolve_database_option('port', data_source, connection_params, restore=True)
tls = utils.resolve_database_option('tls', data_source, restore=True)
port = ds_config.resolve_database_option('port', data_source, connection_params, restore=True)
tls = ds_config.resolve_database_option('tls', data_source, restore=True)
username = borgmatic.hooks.credential.parse.resolve_credential(
utils.resolve_database_option('username', data_source, connection_params, restore=True),
ds_config.resolve_database_option('username', data_source, connection_params, restore=True),
config,
)
password = borgmatic.hooks.credential.parse.resolve_credential(
utils.resolve_database_option('password', data_source, connection_params, restore=True),
ds_config.resolve_database_option('password', data_source, connection_params, restore=True),
config,
)
+9 -6
View File
@@ -6,7 +6,8 @@ import borgmatic.borg.pattern
import borgmatic.config.paths
import borgmatic.hooks.credential.parse
from borgmatic.execute import execute_command, execute_command_with_processes
from borgmatic.hooks.data_source import dump, utils
from borgmatic.hooks.data_source import config as ds_config
from borgmatic.hooks.data_source import dump
logger = logging.getLogger(__name__)
@@ -139,7 +140,7 @@ def build_dump_command(database, config, dump_filename, dump_format):
dump_command = tuple(
shlex.quote(part) for part in shlex.split(database.get('mongodump_command') or 'mongodump')
)
hostname = utils.resolve_database_option('hostname', database)
hostname = ds_config.resolve_database_option('hostname', database)
return (
dump_command
+ (('--out', shlex.quote(dump_filename)) if dump_format == 'directory' else ())
@@ -272,14 +273,16 @@ def build_restore_command(extract_process, database, config, dump_filename, conn
'''
Return the custom mongorestore_command from a single database configuration.
'''
hostname = utils.resolve_database_option('hostname', database, connection_params, restore=True)
port = utils.resolve_database_option('port', database, connection_params, restore=True)
hostname = ds_config.resolve_database_option(
'hostname', database, connection_params, restore=True
)
port = ds_config.resolve_database_option('port', database, connection_params, restore=True)
username = borgmatic.hooks.credential.parse.resolve_credential(
utils.resolve_database_option('username', database, connection_params, restore=True),
ds_config.resolve_database_option('username', database, connection_params, restore=True),
config,
)
password = borgmatic.hooks.credential.parse.resolve_credential(
utils.resolve_database_option('password', database, connection_params, restore=True),
ds_config.resolve_database_option('password', database, connection_params, restore=True),
config,
)
+9 -8
View File
@@ -12,7 +12,8 @@ from borgmatic.execute import (
execute_command_and_capture_output,
execute_command_with_processes,
)
from borgmatic.hooks.data_source import dump, utils
from borgmatic.hooks.data_source import config as ds_config
from borgmatic.hooks.data_source import dump
logger = logging.getLogger(__name__)
@@ -47,7 +48,7 @@ def database_names_to_dump(database, config, username, password, environment, dr
borgmatic.hooks.data_source.mariadb.parse_extra_options(database.get('list_options'))
)
password_transport = database.get('password_transport', 'pipe')
hostname = utils.resolve_database_option('hostname', database)
hostname = ds_config.resolve_database_option('hostname', database)
show_command = (
mysql_show_command
+ (
@@ -121,7 +122,7 @@ def execute_dump_command(
borgmatic.hooks.data_source.mariadb.parse_extra_options(database.get('options'))
)
password_transport = database.get('password_transport', 'pipe')
hostname = utils.resolve_database_option('hostname', database)
hostname = ds_config.resolve_database_option('hostname', database)
dump_command = (
mysql_dump_command
+ (
@@ -348,17 +349,17 @@ def restore_data_source_dump(
subprocess.Popen) to produce output to consume.
'''
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
hostname = utils.resolve_database_option(
hostname = ds_config.resolve_database_option(
'hostname', data_source, connection_params, restore=True
)
port = utils.resolve_database_option('port', data_source, connection_params, restore=True)
tls = utils.resolve_database_option('tls', data_source, restore=True)
port = ds_config.resolve_database_option('port', data_source, connection_params, restore=True)
tls = ds_config.resolve_database_option('tls', data_source, restore=True)
username = borgmatic.hooks.credential.parse.resolve_credential(
utils.resolve_database_option('username', data_source, connection_params, restore=True),
ds_config.resolve_database_option('username', data_source, connection_params, restore=True),
config,
)
password = borgmatic.hooks.credential.parse.resolve_credential(
utils.resolve_database_option('password', data_source, connection_params, restore=True),
ds_config.resolve_database_option('password', data_source, connection_params, restore=True),
config,
)
+8 -7
View File
@@ -13,7 +13,8 @@ from borgmatic.execute import (
execute_command_and_capture_output,
execute_command_with_processes,
)
from borgmatic.hooks.data_source import dump, utils
from borgmatic.hooks.data_source import config as ds_config
from borgmatic.hooks.data_source import dump
logger = logging.getLogger(__name__)
@@ -32,7 +33,7 @@ def make_environment(database, config, restore_connection_params=None):
'''
environment = dict(os.environ)
password = utils.resolve_database_option(
password = ds_config.resolve_database_option(
'password', database, restore_connection_params, restore=restore_connection_params
)
@@ -84,7 +85,7 @@ def database_names_to_dump(database, config, environment, dry_run):
psql_command = tuple(
shlex.quote(part) for part in shlex.split(database.get('psql_command') or 'psql')
)
hostname = utils.resolve_database_option('hostname', database)
hostname = ds_config.resolve_database_option('hostname', database)
list_command = (
psql_command
+ ('--list', '--no-password', '--no-psqlrc', '--csv', '--tuples-only')
@@ -189,7 +190,7 @@ def dump_data_sources(
)
continue
hostname = utils.resolve_database_option('hostname', database)
hostname = ds_config.resolve_database_option('hostname', database)
command = (
dump_command
+ (
@@ -335,12 +336,12 @@ def restore_data_source_dump(
hostname, port, username, and password.
'''
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
hostname = utils.resolve_database_option(
hostname = ds_config.resolve_database_option(
'hostname', data_source, connection_params, restore=True
)
port = utils.resolve_database_option('port', data_source, connection_params, restore=True)
port = ds_config.resolve_database_option('port', data_source, connection_params, restore=True)
username = borgmatic.hooks.credential.parse.resolve_credential(
utils.resolve_database_option('username', data_source, connection_params, restore=True),
ds_config.resolve_database_option('username', data_source, connection_params, restore=True),
config,
)
@@ -9,7 +9,7 @@ import pymongo
import pytest
import ruamel.yaml
from borgmatic.hooks.data_source import utils
from borgmatic.hooks.data_source import config
def write_configuration(
@@ -221,10 +221,10 @@ postgresql_databases:
def get_connection_params(database, use_restore_options=False):
hostname = utils.resolve_database_option('hostname', database, restore=use_restore_options)
port = utils.resolve_database_option('port', database, restore=use_restore_options)
username = utils.resolve_database_option('username', database, restore=use_restore_options)
password = utils.resolve_database_option('password', database, restore=use_restore_options)
hostname = config.resolve_database_option('hostname', database, restore=use_restore_options)
port = config.resolve_database_option('port', database, restore=use_restore_options)
username = config.resolve_database_option('username', database, restore=use_restore_options)
password = config.resolve_database_option('password', database, restore=use_restore_options)
return (hostname, port, username, password)
@@ -0,0 +1,93 @@
from subprocess import CalledProcessError
import pytest
from flexmock import flexmock
from borgmatic.hooks.data_source import config
def test_get_database_option():
data_source = {'option': 'original_value', 'restore_option': 'restore_value'}
connection_params = {'option': 'connection_value'}
assert config.resolve_database_option('option', data_source) == 'original_value'
assert config.resolve_database_option('option', data_source, restore=True) == 'restore_value'
assert (
config.resolve_database_option('option', data_source, connection_params)
== 'connection_value'
)
assert (
config.resolve_database_option('option', data_source, connection_params, restore=True)
== 'connection_value'
)
def test_get_hostname_option_via_container():
data_source = {
'container': 'original_container',
'hostname': 'original_hostname',
'restore_container': 'restore_container',
'restore_hostname': 'restore_hostname',
}
connection_params = {'container': 'connection_container', 'hostname': 'connection_hostname'}
flexmock(config).should_receive('get_ip_from_container').with_args(
'original_container'
).and_return('container_ip_1')
flexmock(config).should_receive('get_ip_from_container').with_args(
'connection_container'
).and_return('container_ip_2')
flexmock(config).should_receive('get_ip_from_container').with_args(
'restore_container'
).and_return('container_ip_3')
assert config.resolve_database_option('hostname', data_source) == 'container_ip_1'
assert (
config.resolve_database_option('hostname', data_source, connection_params)
== 'container_ip_2'
)
assert config.resolve_database_option('hostname', data_source, restore=True) == 'container_ip_3'
def test_get_container_ip_without_engines():
flexmock(config.shutil).should_receive('which').and_return(None).and_return(None)
with pytest.raises(ValueError):
config.get_ip_from_container('yolo')
def test_get_container_ip_success():
flexmock(config.shutil).should_receive('which').and_return(None).and_return('/usr/bin/podman')
flexmock(config).should_receive('execute_command_and_capture_output').and_return(
'{"IPAddress": "1.2.3.4"}'
)
addr = config.get_ip_from_container('yolo')
assert addr == '1.2.3.4'
flexmock(config).should_receive('execute_command_and_capture_output').and_return(
'{"Networks": {"my_network": {"IPAddress": "5.6.7.8"}}}'
)
assert config.get_ip_from_container('yolo') == '5.6.7.8'
def test_get_container_ip_container_not_found():
flexmock(config.shutil).should_receive('which').and_return('/usr/bin/podman')
flexmock(config).should_receive('execute_command_and_capture_output').and_raise(
CalledProcessError, 1, ['/usr/bin/podman', 'inspect', 'yolo'], None, 'No such object'
)
with pytest.raises(CalledProcessError):
config.get_ip_from_container('does not exist')
def test_get_container_ip_container_no_network():
flexmock(config.shutil).should_receive('which').and_return(None).and_return('/usr/bin/podman')
flexmock(config).should_receive('execute_command_and_capture_output').and_return('{}')
with pytest.raises(ValueError) as exc_info:
config.get_ip_from_container('yolo')
assert 'Could not determine ip address for container' in str(exc_info.value)
@@ -1,93 +0,0 @@
from subprocess import CalledProcessError
import pytest
from flexmock import flexmock
from borgmatic.hooks.data_source import utils
def test_get_database_option():
data_source = {'option': 'original_value', 'restore_option': 'restore_value'}
connection_params = {'option': 'connection_value'}
assert utils.resolve_database_option('option', data_source) == 'original_value'
assert utils.resolve_database_option('option', data_source, restore=True) == 'restore_value'
assert (
utils.resolve_database_option('option', data_source, connection_params)
== 'connection_value'
)
assert (
utils.resolve_database_option('option', data_source, connection_params, restore=True)
== 'connection_value'
)
def test_get_hostname_option_via_container():
data_source = {
'container': 'original_container',
'hostname': 'original_hostname',
'restore_container': 'restore_container',
'restore_hostname': 'restore_hostname',
}
connection_params = {'container': 'connection_container', 'hostname': 'connection_hostname'}
flexmock(utils).should_receive('get_ip_from_container').with_args(
'original_container'
).and_return('container_ip_1')
flexmock(utils).should_receive('get_ip_from_container').with_args(
'connection_container'
).and_return('container_ip_2')
flexmock(utils).should_receive('get_ip_from_container').with_args(
'restore_container'
).and_return('container_ip_3')
assert utils.resolve_database_option('hostname', data_source) == 'container_ip_1'
assert (
utils.resolve_database_option('hostname', data_source, connection_params)
== 'container_ip_2'
)
assert utils.resolve_database_option('hostname', data_source, restore=True) == 'container_ip_3'
def test_get_container_ip_without_engines():
flexmock(utils.shutil).should_receive('which').and_return(None).and_return(None)
with pytest.raises(ValueError):
utils.get_ip_from_container('yolo')
def test_get_container_ip_success():
flexmock(utils.shutil).should_receive('which').and_return(None).and_return('/usr/bin/podman')
flexmock(utils).should_receive('execute_command_and_capture_output').and_return(
'{"IPAddress": "1.2.3.4"}'
)
addr = utils.get_ip_from_container('yolo')
assert addr == '1.2.3.4'
flexmock(utils).should_receive('execute_command_and_capture_output').and_return(
'{"Networks": {"my_network": {"IPAddress": "5.6.7.8"}}}'
)
assert utils.get_ip_from_container('yolo') == '5.6.7.8'
def test_get_container_ip_container_not_found():
flexmock(utils.shutil).should_receive('which').and_return('/usr/bin/podman')
flexmock(utils).should_receive('execute_command_and_capture_output').and_raise(
CalledProcessError, 1, ['/usr/bin/podman', 'inspect', 'yolo'], None, 'No such object'
)
with pytest.raises(CalledProcessError):
utils.get_ip_from_container('does not exist')
def test_get_container_ip_container_no_network():
flexmock(utils.shutil).should_receive('which').and_return(None).and_return('/usr/bin/podman')
flexmock(utils).should_receive('execute_command_and_capture_output').and_return('{}')
with pytest.raises(ValueError) as exc_info:
utils.get_ip_from_container('yolo')
assert 'Could not determine ip address for container' in str(exc_info.value)