From 4d320d2908951a1576e548cd00e526ca0540736c Mon Sep 17 00:00:00 2001 From: Vishakha Agarwal Date: Thu, 19 Apr 2018 16:45:22 +0530 Subject: [PATCH] Restoring Encrypted Backup with encrypt-file. Encryption of backup/restore when encrypt-pass-file is passed for nova and cinder. Change-Id: I2c52ac75c7252d783aee5b1321418e2192a083d2 Closes-Bug: #1676404 --- freezer/engine/nova/nova.py | 42 +++++++++++++++++++++++++++++++ freezer/engine/osbrick/osbrick.py | 6 ++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/freezer/engine/nova/nova.py b/freezer/engine/nova/nova.py index 0d02f9cc..4a60aadb 100644 --- a/freezer/engine/nova/nova.py +++ b/freezer/engine/nova/nova.py @@ -22,9 +22,11 @@ from oslo_log import log from freezer.common import client_manager from freezer.engine import engine +from freezer.engine.tar import tar from freezer.utils import utils import json +import tempfile LOG = log.getLogger(__name__) CONF = cfg.CONF @@ -39,7 +41,16 @@ class NovaEngine(engine.BackupEngine): self.glance = self.client.create_glance() self.cinder = self.client.create_cinder() self.neutron = self.client.create_neutron() + self.encrypt_pass_file = kwargs.get('encrypt_key') + self.exclude = kwargs.get('exclude') self.server_info = None + self.openssl_path = None + self.compression_algo = 'gzip' + self.is_windows = None + self.dry_run = kwargs.get('dry_run', False) + self.max_segment_size = kwargs.get('max_segment_size') + self.storage = storage + self.dereference_symlink = kwargs.get('symlinks') @property def name(self): @@ -93,6 +104,9 @@ class NovaEngine(engine.BackupEngine): def restore_level(self, restore_resource, read_pipe, backup, except_queue): try: metadata = backup.metadata() + if (not self.encrypt_pass_file and + metadata.get("encryption", False)): + raise Exception("Cannot restore encrypted backup without key") engine_metadata = backup.engine_metadata() server_info = metadata.get('server', {}) length = int(engine_metadata.get('length')) @@ -116,6 +130,23 @@ class NovaEngine(engine.BackupEngine): data=data ) + if self.encrypt_pass_file: + try: + tmpdir = tempfile.mkdtemp() + except Exception: + LOG.error("Unable to create a tmp directory") + raise + + tar_engine = tar.TarEngine(self.compression_algo, + self.dereference_symlink, + self.exclude, self.storage, + self.max_segment_size, + self.encrypt_pass_file, + self.dry_run) + + tar_engine.restore_level(tmpdir, read_pipe, backup, + except_queue) + utils.wait_for( NovaEngine.image_active, 1, @@ -267,6 +298,16 @@ class NovaEngine(engine.BackupEngine): for chunk in stream: yield chunk + if self.encrypt_pass_file: + tar_engine = tar.TarEngine(self.compression_algo, + self.dereference_symlink, + self.exclude, self.storage, + self.max_segment_size, + self.encrypt_pass_file, self.dry_run) + + for data_chunk in tar_engine.backup_data('.', manifest_path): + yield data_chunk + if image_temporary_snapshot_id is not None: LOG.info("Deleting temporary snapshot {0}" .format(image_temporary_snapshot_id)) @@ -292,6 +333,7 @@ class NovaEngine(engine.BackupEngine): return { "engine_name": self.name, "server": server_info, + "encryption": bool(self.encrypt_pass_file) } def set_tenant_meta(self, path, metadata): diff --git a/freezer/engine/osbrick/osbrick.py b/freezer/engine/osbrick/osbrick.py index e969f2a9..fcf82283 100644 --- a/freezer/engine/osbrick/osbrick.py +++ b/freezer/engine/osbrick/osbrick.py @@ -59,7 +59,8 @@ class OsbrickEngine(engine.BackupEngine): """Construct metadata""" return { "engine_name": self.name, - "volume_info": self.volume_info + "volume_info": self.volume_info, + "encryption": bool(self.encrypt_pass_file) } @staticmethod @@ -156,6 +157,9 @@ class OsbrickEngine(engine.BackupEngine): restore_path)) new_volume = False metadata = backup.metadata() + if (not self.encrypt_pass_file and + metadata.get("encryption", False)): + raise Exception("Cannot restore encrypted backup without key") volume_info = metadata.get("volume_info") try: backup_volume = self.cinder.volumes.get(restore_path)