瀏覽代碼

support command line args for hostname port username password

Divyansh Singh 2 年之前
父節點
當前提交
230cf6adc4
共有 3 個文件被更改,包括 51 次插入11 次删除
  1. 16 1
      borgmatic/actions/restore.py
  2. 15 0
      borgmatic/commands/arguments.py
  3. 20 10
      borgmatic/hooks/postgresql.py

+ 16 - 1
borgmatic/actions/restore.py

@@ -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

+ 15 - 0
borgmatic/commands/arguments.py

@@ -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'
     )

+ 20 - 10
borgmatic/hooks/postgresql.py

@@ -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: