From ee31dc37a9814cb9ebd8c3299f5b9d8a56887469 Mon Sep 17 00:00:00 2001 From: smukunda Date: Tue, 10 Jun 2025 14:52:10 -0400 Subject: [PATCH] Changes to Restore code. Change-Id: I24c7f47dddc1329637ce8e0907593692556bf9f8 Signed-off-by: smukunda --- .../ansible_playbook_keywords.py | 36 +++++++++++++-- ...ansible_playbook_backup_restore_output.py} | 12 ++--- .../restore_files_upload_keywords.py | 44 +++++++++++++++++++ .../backup_and_restore/test_system_restore.py | 43 ++++++++++++++++++ 4 files changed, 125 insertions(+), 10 deletions(-) rename keywords/cloud_platform/ansible_playbook/object/{ansible_playbook_backup_output.py => ansible_playbook_backup_restore_output.py} (84%) create mode 100644 keywords/cloud_platform/ansible_playbook/restore_files_upload_keywords.py diff --git a/keywords/cloud_platform/ansible_playbook/ansible_playbook_keywords.py b/keywords/cloud_platform/ansible_playbook/ansible_playbook_keywords.py index f9c069ae..6456d1e5 100644 --- a/keywords/cloud_platform/ansible_playbook/ansible_playbook_keywords.py +++ b/keywords/cloud_platform/ansible_playbook/ansible_playbook_keywords.py @@ -1,7 +1,7 @@ from config.configuration_manager import ConfigurationManager from framework.logging.automation_logger import get_logger from keywords.base_keyword import BaseKeyword -from keywords.cloud_platform.ansible_playbook.object.ansible_playbook_backup_output import AnsiblePlaybookBackUpOutput +from keywords.cloud_platform.ansible_playbook.object.ansible_playbook_backup_restore_output import AnsiblePlaybookBackUpRestoreOutput class AnsiblePlaybookKeywords(BaseKeyword): @@ -21,7 +21,7 @@ class AnsiblePlaybookKeywords(BaseKeyword): Executes the `ansible-playbook` backup command and returns the parsed output. Args: - backup_dir (str): backuo playbook path + backup_dir (str): backup playbook path backup_registry (bool): backup registry Returns: @@ -38,5 +38,33 @@ class AnsiblePlaybookKeywords(BaseKeyword): cmd_out = self.ssh_connection.send(command, reconnect_timeout=3600) self.validate_success_return_code(self.ssh_connection) get_logger().log_info("get ansible playbook backup output") - backup_output = AnsiblePlaybookBackUpOutput(cmd_out) - return backup_output.validate_ansible_playbook_backup_result() + backup_output = AnsiblePlaybookBackUpRestoreOutput(cmd_out) + return backup_output.validate_ansible_playbook_backup_restore_result() + + def ansible_playbook_restore(self, backup_dir: str, restore_mode: str = "optimized", restore_registry: bool = True) -> bool: + """ + Executes the ansible-playbook restore command + + Args: + backup_dir (str): Directory where backup file is stored + restore_mode (str): Restore mode (default: optimized) + restore_registry (bool): Whether to restore the registry filesystem + + Returns: + bool: True if restore succeeded + """ + restore_playbook_path = "/usr/share/ansible/stx-ansible/playbooks/restore_platform.yml" + admin_password = ConfigurationManager.get_lab_config().get_admin_credentials().get_password() + restore_registry_arg = '-e "restore_registry_filesystem=true"' if restore_registry else "" + + # Get the latest backup file + cmd = f"ls {backup_dir}/*_platform_backup_*.tgz | tail -n 1 | xargs basename" + backup_filename = self.ssh_connection.send(cmd)[0].strip() + + command = f"ansible-playbook {restore_playbook_path} " f'-e "ansible_become_pass={admin_password}" ' f'-e "admin_password={admin_password}" ' f'-e "initial_backup_dir={backup_dir}" ' f'-e "backup_filename={backup_filename}" ' f'-e "restore_mode={restore_mode}" ' f"{restore_registry_arg}" + + cmd_out = self.ssh_connection.send(command, reconnect_timeout=3600) + self.validate_success_return_code(self.ssh_connection) + get_logger().log_info("get ansible playbook restore output") + restore_output = AnsiblePlaybookBackUpRestoreOutput(cmd_out) + return restore_output.validate_ansible_playbook_backup_restore_result() diff --git a/keywords/cloud_platform/ansible_playbook/object/ansible_playbook_backup_output.py b/keywords/cloud_platform/ansible_playbook/object/ansible_playbook_backup_restore_output.py similarity index 84% rename from keywords/cloud_platform/ansible_playbook/object/ansible_playbook_backup_output.py rename to keywords/cloud_platform/ansible_playbook/object/ansible_playbook_backup_restore_output.py index b9f5bdb8..9ffed0e6 100644 --- a/keywords/cloud_platform/ansible_playbook/object/ansible_playbook_backup_output.py +++ b/keywords/cloud_platform/ansible_playbook/object/ansible_playbook_backup_restore_output.py @@ -1,9 +1,9 @@ from framework.logging.automation_logger import get_logger -class AnsiblePlaybookBackUpOutput: +class AnsiblePlaybookBackUpRestoreOutput: """ - This class parses the output of 'Ansible-playbook backup' command to verify the output. + This class parses the output of 'Ansible-playbook backup and Restore' command to verify the output. """ def __init__(self, cmd_output: str): @@ -15,7 +15,7 @@ class AnsiblePlaybookBackUpOutput: """ self.cmd_output = cmd_output - def validate_ansible_playbook_backup_result(self) -> bool: + def validate_ansible_playbook_backup_restore_result(self) -> bool: """ Checks if the output contains all the expected values. @@ -46,6 +46,6 @@ class AnsiblePlaybookBackUpOutput: failed = [i for i in result if "failed" in i] if failed: if int(failed[0].split("=")[1]) == 0: - successful_backup = True - get_logger().log_info(f"successful backup : {successful_backup}") - return successful_backup + successful_backup_restore = True + get_logger().log_info(f"successful ansible : {successful_backup_restore}") + return successful_backup_restore diff --git a/keywords/cloud_platform/ansible_playbook/restore_files_upload_keywords.py b/keywords/cloud_platform/ansible_playbook/restore_files_upload_keywords.py new file mode 100644 index 00000000..549a90f5 --- /dev/null +++ b/keywords/cloud_platform/ansible_playbook/restore_files_upload_keywords.py @@ -0,0 +1,44 @@ +import os + +from framework.logging.automation_logger import get_logger +from keywords.base_keyword import BaseKeyword +from keywords.files.file_keywords import FileKeywords + + +class RestoreFilesUploadKeywords(BaseKeyword): + """Provides keyword functions to upload backup files to controller before restore.""" + + def __init__(self, ssh_connection: str): + """Initializes AnsiblePlaybookKeywords with an SSH connection. + + Args: + ssh_connection (str): SSH connection to the target system. + """ + self.ssh_connection = ssh_connection + + def restore_file(self, local_backup_folder_path: str, remote_backup_dir: str) -> bool: + """ + Upload backup file(s) from local to controller + + Args: + local_backup_folder_path (str): Path on local test machine + remote_backup_dir (str): Path on controller where backup files are placed + + Returns: + bool: Whether upload was successful + """ + get_logger().log_info("Checking and uploading backup files to controller") + backup_files = os.listdir(local_backup_folder_path) + if not backup_files: + get_logger().log_error("No backup files found locally") + raise Exception(f"No backup file available to perform the restore") + + upload_status = False + for file_name in backup_files: + if "backup" in file_name: + local_path = os.path.join(local_backup_folder_path, file_name) + remote_path = os.path.join(remote_backup_dir, file_name) + upload_status = FileKeywords(self.ssh_connection).upload_file(local_path, remote_path) + + return upload_status + diff --git a/testcases/cloud_platform/backup_and_restore/test_system_restore.py b/testcases/cloud_platform/backup_and_restore/test_system_restore.py index e69de29b..613ebb83 100644 --- a/testcases/cloud_platform/backup_and_restore/test_system_restore.py +++ b/testcases/cloud_platform/backup_and_restore/test_system_restore.py @@ -0,0 +1,43 @@ +from pytest import mark + +from framework.logging.automation_logger import get_logger +from framework.validation.validation import validate_equals +from keywords.cloud_platform.ansible_playbook.ansible_playbook_keywords import AnsiblePlaybookKeywords +from keywords.cloud_platform.ansible_playbook.restore_files_upload_keywords import RestoreFilesUploadKeywords +from keywords.cloud_platform.ssh.lab_connection_keywords import LabConnectionKeywords +from keywords.cloud_platform.system.host.system_host_list_keywords import SystemHostListKeywords +from keywords.cloud_platform.system.host.system_host_lock_keywords import SystemHostLockKeywords + +@mark.p0 +def test_restore(): + """ + Test system restore using ansible playbook + + Test Steps: + - Copy backup file to target controller + - Run restore playbook + - Unlock host + - Validate restore completion + """ + + backup_dir = "/opt/platform-backup/localhost" + local_backup_folder_path = "/tmp/bnr" + ssh_connection = LabConnectionKeywords().get_active_controller_ssh() + active_controller = SystemHostListKeywords(ssh_connection).get_active_controller() + + get_logger().log_info("Copy backup files from local to target controller") + restore_file_status = RestoreFilesUploadKeywords(ssh_connection).restore_file(local_backup_folder_path, backup_dir) + validate_equals(restore_file_status, True, "Backup file copy to controller") + get_logger().log_info("Backup file copy to controller completed successfully") + + get_logger().log_info("Run restore ansible playbook") + ansible_playbook_restore_output = AnsiblePlaybookKeywords(ssh_connection).ansible_playbook_restore(backup_dir) + validate_equals(ansible_playbook_restore_output, True, "Ansible restore command execution") + + get_logger().log_info("Unlocking controller host") + ssh_connection = LabConnectionKeywords().get_active_controller_ssh() + active_controller = SystemHostListKeywords(ssh_connection).get_active_controller() + unlock_success = SystemHostLockKeywords(ssh_connection).unlock_host(active_controller.get_host_name()) + validate_equals(unlock_success, True, "Validate controller was unlocked successfully") + +