support command line args for hostname port username password

This commit is contained in:
Divyansh Singh 2023-06-14 00:11:19 +05:30
parent 8e8e64d920
commit 230cf6adc4
3 changed files with 51 additions and 11 deletions

View file

@ -68,15 +68,21 @@ def restore_single_database(
archive_name,
hook_name,
database,
connection_params,
): # pragma: no cover
'''
Given (among other things) an archive name, a database hook name, and a configured database
Given (among other things) an archive name, a database hook name, the hostname,
port, username and password as connection params, and a configured database
configuration dict, restore that database from the archive.
'''
logger.info(
f'{repository.get("label", repository["path"])}: Restoring database {database["name"]}'
)
logger.info(
f'hostname port username password for database {database["name"]}'
)
dump_pattern = borgmatic.hooks.dispatch.call_hooks(
'make_database_dump_pattern',
hooks,
@ -113,6 +119,7 @@ def restore_single_database(
location,
global_arguments.dry_run,
extract_process,
connection_params,
)
@ -308,6 +315,13 @@ def run_restore(
hooks, archive_database_names, hook_name, database_name
)
connection_params = {
'hostname': restore_arguments.hostname,
'port': restore_arguments.port,
'username': restore_arguments.username,
'password': restore_arguments.password,
}
if not found_database:
remaining_restore_names.setdefault(found_hook_name or hook_name, []).append(
database_name
@ -327,6 +341,7 @@ def run_restore(
archive_name,
found_hook_name or hook_name,
dict(found_database, **{'schemas': restore_arguments.schemas}),
connection_params,
)
# For any database that weren't found via exact matches in the hooks configuration, try to

View file

@ -720,6 +720,21 @@ def make_parsers():
dest='schemas',
help='Names of schemas to restore from the database, defaults to all schemas. Schemas are only supported for PostgreSQL and MongoDB databases',
)
restore_group.add_argument(
'--hostname',
help='Database hostname to restore to. Defaults to the "restore_hostname" option in borgmatic\'s configuration',
)
restore_group.add_argument(
'--port', help='Port to restore to. Defaults to the "restore_port" option in borgmatic\'s configuration'
)
restore_group.add_argument(
'--username',
help='Username with which to connect to the database. Defaults to the "restore_username" option in borgmatic\'s configuration',
)
restore_group.add_argument(
'--password',
help='Password with which to connect to the restore database. Defaults to the "restore_password" option in borgmatic\'s configuration',
)
restore_group.add_argument(
'-h', '--help', action='help', help='Show this help message and exit'
)

View file

@ -22,8 +22,7 @@ def make_dump_path(location_config): # pragma: no cover
location_config.get('borgmatic_source_directory'), 'postgresql_databases'
)
def make_extra_environment(database, restore=False):
def make_extra_environment(database, restore=False, connection_params=None):
'''
Make the extra_environment dict from the given database configuration.
'''
@ -32,6 +31,8 @@ def make_extra_environment(database, restore=False):
extra['PGPASSWORD'] = database['password']
if restore and 'restore_password' in database:
extra['PGPASSWORD'] = database['restore_password']
if connection_params is not None and connection_params.get('password'):
extra['PGPASSWORD'] = connection_params['password']
extra['PGSSLMODE'] = database.get('ssl_mode', 'disable')
if 'ssl_cert' in database:
extra['PGSSLCERT'] = database['ssl_cert']
@ -195,7 +196,7 @@ def make_database_dump_pattern(
return dump.make_database_dump_filename(make_dump_path(location_config), name, hostname='*')
def restore_database_dump(database_config, log_prefix, location_config, dry_run, extract_process):
def restore_database_dump(database_config, log_prefix, location_config, dry_run, extract_process, connection_params):
'''
Restore the given PostgreSQL database from an extract stream. The database is supplied as a
one-element sequence containing a dict describing the database, as per the configuration schema.
@ -205,6 +206,9 @@ def restore_database_dump(database_config, log_prefix, location_config, dry_run,
If the extract process is None, then restore the dump from the filesystem rather than from an
extract stream.
Use the given connection parameters to connect to the database. The connection parameters are
hostname, port, username, and password.
'''
dry_run_label = ' (dry run; not actually restoring anything)' if dry_run else ''
@ -212,6 +216,12 @@ def restore_database_dump(database_config, log_prefix, location_config, dry_run,
raise ValueError('The database configuration value is invalid')
database = database_config[0]
hostname = connection_params['hostname'] or database.get('restore_hostname', database.get('hostname'))
port = str(connection_params['port'] or database.get('restore_port', database.get('port')))
username = connection_params['username'] or database.get('restore_username', database.get('username'))
password = connection_params['password'] or database.get('restore_password', database.get('password'))
all_databases = bool(database['name'] == 'all')
dump_filename = dump.make_database_dump_filename(
make_dump_path(location_config), database['name'], database.get('hostname')
@ -220,9 +230,9 @@ def restore_database_dump(database_config, log_prefix, location_config, dry_run,
analyze_command = (
tuple(psql_command)
+ ('--no-password', '--no-psqlrc', '--quiet')
+ (('--host', database.get('restore_hostname', database.get('hostname'))) if 'hostname' in database else ())
+ (('--port', str(database.get('restore_port', database.get('port')))) if 'port' in database else ())
+ (('--username', database.get('restore_username', database.get('username'))) if 'username' in database else ())
+ (('--host', hostname) if 'hostname' in database or 'restore_hostname' in database or 'hostname' in connection_params else ())
+ (('--port', port) if 'port' in database or 'restore_port' in database or 'port' in connection_params else ())
+ (('--username', username) if 'username' in database or 'restore_username' in database or 'username' in connection_params else ())
+ (('--dbname', database['name']) if not all_databases else ())
+ (tuple(database['analyze_options'].split(' ')) if 'analyze_options' in database else ())
+ ('--command', 'ANALYZE')
@ -234,9 +244,9 @@ def restore_database_dump(database_config, log_prefix, location_config, dry_run,
+ ('--no-password',)
+ (('--no-psqlrc',) if use_psql_command else ('--if-exists', '--exit-on-error', '--clean'))
+ (('--dbname', database['name']) if not all_databases else ())
+ (('--host', database.get('restore_hostname', database.get('hostname'))) if 'hostname' in database or 'restore_hostname' in database else ())
+ (('--port', str(database.get('restore_port', database.get('port')))) if 'port' in database or 'restore_port' in database else ())
+ (('--username', database.get('restore_username', database.get('username'))) if 'username' in database or 'restore_username' in database else ())
+ (('--host', hostname) if 'hostname' in database or 'restore_hostname' in database or 'hostname' in connection_params else ())
+ (('--port', port) if 'port' in database or 'restore_port' in database or 'port' in connection_params else ())
+ (('--username', username) if 'username' in database or 'restore_username' in database or 'username' in connection_params else ())
+ (('--no-owner',) if database['no_owner'] else ())
+ (tuple(database['restore_options'].split(' ')) if 'restore_options' in database else ())
+ (() if extract_process else (dump_filename,))
@ -247,7 +257,7 @@ def restore_database_dump(database_config, log_prefix, location_config, dry_run,
)
)
extra_environment = make_extra_environment(database, restore=True)
extra_environment = make_extra_environment(database, restore=True, connection_params=connection_params)
logger.debug(f"{log_prefix}: Restoring PostgreSQL database {database['name']}{dry_run_label}")
if dry_run: