def process(self):

        if self.level == 'node':
            new_conf_url = 'yaml:///opt/seagate/cortx/sspl/conf/sspl.conf.LR2.yaml'
            merged_conf_url = 'yaml:///opt/seagate/cortx/sspl/tmp/merged.conf'
            # Only proceed if both existing and new config path are present
            for filepath in [sspl_config_path, new_conf_url]:
                if not os.path.exists(filepath.split(":/")[1]):
                    logger.debug(
                        "Config not upgraded as existing or new config file is not present."
                    )
                    return
            conf_upgrade = ConfUpgrade(sspl_config_path, new_conf_url,
                                       merged_conf_url)
            try:
                conf_upgrade.create_merged_config()
            except ConfError as e:
                logger.error(
                    "%s error seen while upgrading config, existing config retained"
                    % e)
            else:
                conf_upgrade.upgrade_existing_config()
            finally:
                conf_upgrade.remove_merged_config()

        elif self.level == 'cluster':
            # No action needed
            pass
Exemple #2
0
    def validate(self):
        """Check for below requirement.

        1. Validate input configs
        2. Validate sspl conf is created
        3. Check if message bus is accessible
        """
        if os.geteuid() != 0:
            msg = "Run this command with root privileges."
            logger.error(msg)
            raise SetupError(errno.EINVAL, msg)

        # Validate input/provisioner configs
        machine_id = Utility.get_machine_id()
        Utility.get_config_value(consts.PRVSNR_CONFIG_INDEX,
                                 "server_node>%s>cluster_id" % machine_id)
        self.node_type = Utility.get_config_value(
            consts.PRVSNR_CONFIG_INDEX, "server_node>%s>type" % machine_id)
        enclosure_id = Utility.get_config_value(
            consts.PRVSNR_CONFIG_INDEX,
            "server_node>%s>storage>enclosure_id" % machine_id)
        self.enclosure_type = Utility.get_config_value(
            consts.PRVSNR_CONFIG_INDEX,
            "storage_enclosure>%s>type" % enclosure_id)

        # Validate sspl conf is created
        if not os.path.isfile(consts.file_store_config_path):
            msg = "Missing configuration - %s !! Create and rerun." % (
                consts.file_store_config_path)
            logger.error(msg)
            raise SetupError(errno.EINVAL, msg)

        # Validate message bus is accessible
        self.mb = MessageBus()
Exemple #3
0
 def enable_sspl_service(self):
     """Enable sspl-ll service."""
     self.dbus_service.enable("sspl-ll.service")
     daemon_reload_cmd = "systemctl daemon-reload"
     output, error, rc = SimpleProcess(daemon_reload_cmd).run()
     if rc != 0:
         logger.error(f"Failed in enable sspl service. ERROR: {error}")
         raise SetupError(rc, error, daemon_reload_cmd)
Exemple #4
0
    def validate(self):
        """Check below requirements are met in setup.
        1. Check if given product is supported by SSPL
        2. Check if given setup is supported by SSPL
        3. Check if required pre-requisites softwares are installed.
        4. Validate BMC connectivity
        5. Validate storage controller connectivity
        """
        machine_id = Utility.get_machine_id()

        # Validate input/provisioner configs
        self.product = Utility.get_config_value(consts.PRVSNR_CONFIG_INDEX,
                                                "cortx>release>product")
        self.setup = Utility.get_config_value(consts.PRVSNR_CONFIG_INDEX,
                                              "cortx>release>setup")
        node_type = Utility.get_config_value(
            consts.PRVSNR_CONFIG_INDEX, "server_node>%s>type" % machine_id)
        if node_type.lower() not in ["vm", "virtual"]:
            bmc_ip = Utility.get_config_value(
                consts.PRVSNR_CONFIG_INDEX,
                "server_node>%s>bmc>ip" % machine_id)
        enclosure_id = Utility.get_config_value(
            consts.PRVSNR_CONFIG_INDEX,
            "server_node>%s>storage>enclosure_id" % machine_id)
        Utility.get_config_value(consts.PRVSNR_CONFIG_INDEX,
                                 "storage_enclosure>%s>type" % enclosure_id)
        primary_ip = Utility.get_config_value(
            consts.PRVSNR_CONFIG_INDEX,
            "storage_enclosure>%s>controller>primary>ip" % enclosure_id)
        secondary_ip = Utility.get_config_value(
            consts.PRVSNR_CONFIG_INDEX,
            "storage_enclosure>%s>controller>secondary>ip" % enclosure_id)

        # Validate product support
        if self.product not in consts.enabled_products:
            msg = "Product '%s' is not in sspl supported product list: %s" % (
                self.product, consts.enabled_products)
            logger.error(msg)
            raise SetupError(errno.EINVAL, msg)

        # Validate setup support
        if self.setup not in consts.setups:
            msg = "Setup '%s' is not in sspl supported setup list: %s" % (
                self.setup, consts.setups)
            logger.error(msg)
            raise SetupError(errno.EINVAL, msg)

        # Validate required pip3s and rpms are installed
        self.validate_dependencies(self.setup)

        # Validate BMC & Storage controller IP reachability
        if node_type.lower() not in ["vm", "virtual"]:
            # cluster_id required for decrypting the secret is only available from
            # the prepare stage. However accessibility validation will be done in
            # prepare stage. So at this time, validating ip reachability is fine.
            NetworkV().validate("connectivity",
                                [bmc_ip, primary_ip, secondary_ip])
Exemple #5
0
 def process(self):
     try:
         if os.path.exists(file_store_config_path):
             os.remove(file_store_config_path)
         shutil.copyfile(
             "%s/conf/sspl.conf.%s.yaml" % (SSPL_BASE_DIR, self.product),
             file_store_config_path)
         logger.info("%s - Process done" % self.name)
     except OSError as e:
         logger.error(f"Failed in Cleanup. ERROR: {e}")
 def process(self):
     args = ' '.join(self._args.args)
     manifest_support_bundle = "%s/%s %s" % (self._script_dir, self.script,
                                             args)
     _, error, rc = SimpleProcess(manifest_support_bundle).run(
         realtime_output=True)
     if rc != 0:
         msg = "%s - validation failure. %s" % (self.name, error)
         logger.error(msg)
         raise SetupError(rc, msg)
     logger.info("%s - Process done" % self.name)
 def validate(self):
     """Validate init command arguments."""
     if not self.args.config:
         msg = "%s - Argument validation failure. %s" % (
             self.name, "Global config is required.")
         logger.error(msg)
         raise SetupError(errno.EINVAL, msg)
     # Validate config inputs
     Conf.load(PRVSNR_CONFIG_INDEX, self.args.config[0])
     self.sspl_init.validate()
     logger.info("%s - validation done" % self.name)
Exemple #8
0
 def validate_group_existence(self):
     max_retry = 3
     for i in range(max_retry):
         sspl_gid = Utility.get_gid(consts.USER)
         if sspl_gid != -1:
             break
         else:
             if i == (max_retry - 1):
                 msg = "No group found with name : %s" % (consts.USER)
                 logger.error(msg)
                 raise SetupError(errno.EINVAL, msg)
             time.sleep(1)
 def validate(self):
     # Validate config inputs
     from framework.utils.utility import Utility
     Conf.load(GLOBAL_CONFIG_INDEX, global_config_path)
     self.product = Utility.get_config_value(GLOBAL_CONFIG_INDEX,
                                             "cortx>release>product")
     if self.product is None:
         msg = "%s - validation failure. %s" % (
             self.name,
             "'Product' name is required to restore suitable configs.")
         logger.error(msg)
         raise SetupError(errno.EINVAL, msg)
     logger.info("%s - Validation done" % self.name)
    def validate(self):
        """Validate test command arguments."""
        if not self.args.config:
            msg = "%s - Argument validation failure. %s" % (
                self.name, "Global config is required.")
            logger.error(msg)
            raise SetupError(errno.EINVAL, msg)
        if not self.args.plan:
            msg = "%s - Argument validation failure. Test plan is needed" % (
                self.name)
            logger.error(msg)
            raise SetupError(errno.EINVAL, msg)
        result = PkgV().validate("rpms", "sspl-test")
        if result == -1:
            msg = "'sspl-test' rpm pkg not found."
            logger.error(msg)
            raise SetupError(1, msg)

        # Service restart is required for coverage.
        # Hence it can be enabled only with test plans
        # which are present in TEST_REQ_SERVICE_RESTART list.
        if self.args.coverage and self.args.plan[
                0] not in TEST_REQ_SERVICE_RESTART:
            msg = "Code coverage can not be enabled for %s test plan." \
                % self.args.plan[0]
            logger.error(msg)
            raise SetupError(errno.EINVAL,
                             "%s - Argument validation failure. %s", self.name,
                             msg)
        logger.info("%s - Validation done" % self.name)
Exemple #11
0
 def create_user(self):
     """Add sspl-ll user and validate user creation."""
     os.system("/usr/sbin/useradd -r %s -s /sbin/nologin \
         -c 'User account to run the %s service'" % (consts.USER, consts.USER))
     usernames = [x[0] for x in pwd.getpwall()]
     if consts.USER not in usernames:
         msg = "User %s doesn't exit. Please add user." % (consts.USER)
         logger.error(msg)
         raise SetupError(errno.EINVAL, msg)
     # Add sspl-ll user to required groups and sudoers file etc.
     sspl_reinit = "%s/low-level/framework/sspl_reinit" % consts.SSPL_BASE_DIR
     _ , error, rc = SimpleProcess(sspl_reinit).run()
     if rc:
         msg = "%s failed for with error : %e" % (sspl_reinit, error)
         logger.error(msg)
         raise SetupError(rc, msg)
 def validate_nw_interfaces(self, interfaces):
     """Check network intefaces are up."""
     if not isinstance(interfaces, list):
         msg = "%s - validation failure. %s" % (self.name,
             "Expected list of interfaces. Received, %s." % interfaces)
         logger.error(msg)
         raise SetupError(errno.EINVAL, msg)
     cmd = "ip --br a | awk '{print $1, $2}'"
     nws = [nw.strip() for nw in os.popen(cmd)]
     nw_status = {nw.split(" ")[0]: nw.split(" ")[1] for nw in nws}
     for interface, status in nw_status.items():
         if interface in interfaces and status in ["down", "DOWN"]:
             msg = "%s - validation failure. %s" % (
                 self.name, "Network interface %s is down." % interface)
             logger.error(msg)
             raise SetupError(errno.EINVAL, msg)
Exemple #13
0
    def process(self):
        """Configure sensor monitoring and log level setting."""
        # Update sspl.conf with provisioner supplied input config copy
        Conf.set(consts.SSPL_CONFIG_INDEX,
                 "SYSTEM_INFORMATION>global_config_copy_url",
                 consts.global_config_path)
        Conf.save(consts.SSPL_CONFIG_INDEX)

        if os.path.isfile(consts.SSPL_CONFIGURED):
            os.remove(consts.SSPL_CONFIGURED)

        os.makedirs(consts.SSPL_CONFIGURED_DIR, exist_ok=True)
        with open(consts.SSPL_CONFIGURED, 'a'):
            os.utime(consts.SSPL_CONFIGURED)
        sspl_uid = Utility.get_uid(consts.USER)
        sspl_gid = Utility.get_gid(consts.USER)
        Utility.set_ownership_recursively([consts.SSPL_CONFIGURED], sspl_uid,
                                          sspl_gid)

        # Get the types of server and storage we are currently running on and
        # enable/disable sensor groups in the conf file accordingly.
        update_sensor_info(consts.SSPL_CONFIG_INDEX, self.node_type,
                           self.enclosure_type)

        # Message bus topic creation
        self.create_message_types()

        # Skip this step if sspl is being configured for node replacement
        # scenario as consul data is already
        # available on healthy node
        # Updating build requested log level
        if not os.path.exists(consts.REPLACEMENT_NODE_ENV_VAR_FILE):
            with open(f"{consts.SSPL_BASE_DIR}/low-level/files/opt/seagate" + \
                "/sspl/conf/build-requested-loglevel") as f:
                log_level = f.read().strip()

            if not log_level:
                log_level = "INFO"

            if log_level in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]:
                Conf.set(consts.SSPL_CONFIG_INDEX,
                         "SYSTEM_INFORMATION>log_level", log_level)
                Conf.save(consts.SSPL_CONFIG_INDEX)
            else:
                msg = "Unexpected log level is requested, '%s'" % (log_level)
                logger.error(msg)
                raise SetupError(errno.EINVAL, msg)
    def process(self, product):
        """Reset and cleanup config.

        if self.pre_factory:
            Cleanup sspl log and config files and rollback all steps executed
            in post_install stage.
        else:
            Reset sspl config.
        """
        try:
            if os.path.exists(file_store_config_path):
                FileStore().delete(
                    file_store_config_path)
            shutil.copyfile("%s/conf/sspl.conf.%s.yaml" % (
                SSPL_BASE_DIR, product), file_store_config_path)
            if self.pre_factory:
                self.cleanup_log_and_config()
        except OSError as e:
            logger.error(f"Failed in Cleanup. ERROR: {e}")
Exemple #15
0
    def create_user(self):
        """Add sspl-ll user and validate user creation."""
        command = f"/usr/sbin/useradd -r {consts.USER} -s /sbin/nologin \
                  -c 'User account to run the {consts.USER} service'"

        _, error, rc = SimpleProcess(command).run()
        # rc 9 means user already exists
        if rc != 0 and rc != 9:
            logger.error(f"Failed to create sspl user. ERROR: {error}")
            raise SetupError(rc, error, command)

        self.validate_user_existence()
        self.validate_group_existence()
        # Add sspl-ll user to required groups and sudoers file etc.
        sspl_reinit = "%s/low-level/framework/sspl_reinit" % consts.SSPL_BASE_DIR
        _, error, rc = SimpleProcess(sspl_reinit).run()
        if rc:
            msg = "%s failed for with error : %e" % (sspl_reinit, error)
            logger.error(msg)
            raise SetupError(rc, msg)
    def validate_nw_cable_connection(self, interfaces):
        """Check network interface links are up.

        0 - Cable disconnected
        1 - Cable connected
        """
        if not isinstance(interfaces, list):
            msg = "%s - validation failure. %s" % (self.name,
                "Expected list of interfaces. Received, %s." % interfaces)
            logger.error(msg)
            raise SetupError(errno.EINVAL, msg)
        for interface in interfaces:
            cmd = "cat /sys/class/net/%s/carrier" % interface
            output, error, rc = SimpleProcess(cmd).run()
            output = output.decode().strip()
            if output == "0":
                msg = "%s - validation failure. %s" % (self.name,
                    "Network interface cable is disconnected - %s." % interface)
                logger.error(msg)
                raise SetupError(errno.EINVAL, msg)
Exemple #17
0
    def create_directories_and_ownership(self):
        """Create ras persistent cache directory and state file.

        Assign ownership recursively on the configured directory.
        The created state file will be used later by SSPL resourse agent(HA).
        """
        # Extract the data path
        sspldp = Utility.get_config_value(consts.SSPL_CONFIG_INDEX,
            "SYSTEM_INFORMATION>data_path")
        if not sspldp:
            raise SetupError(errno.EINVAL, "Data path not set in sspl.conf")
        sspl_uid = Utility.get_uid(consts.USER)
        sspl_gid = Utility.get_gid(consts.USER)
        if sspl_uid == -1 or sspl_gid == -1:
            msg = "No user found with name : %s" % (consts.USER)
            logger.error(msg)
            raise SetupError(errno.EINVAL, msg)
        # Create sspl data directory if not exists
        os.makedirs(sspldp, exist_ok=True)
        # Create state file under sspl data directory
        if not os.path.exists(self.state_file):
            file = open(self.state_file, "w")
            file.close()

        # Create SSPL log and bundle directories
        os.makedirs(consts.SSPL_LOG_PATH, exist_ok=True)
        os.makedirs(consts.SSPL_BUNDLE_PATH, exist_ok=True)
        # set ownership for SSPL dirs
        list_root_dir = [consts.SSPL_CONFIGURED_DIR, consts.SSPL_LOG_PATH]
        Utility.set_ownership_recursively(list_root_dir, sspl_uid, sspl_gid)
        # Create /tmp/dcs/hpi if required. Not required for '<product>' role
        if self.setup != "cortx":
            os.makedirs(consts.HPI_PATH, mode=0o777, exist_ok=True)
            zabbix_uid = Utility.get_uid("zabbix")
            if zabbix_uid != -1:
                os.chown(consts.HPI_PATH, zabbix_uid, -1)
        # Create mdadm.conf to set ACL on it.
        with open(consts.MDADM_PATH, 'a'):
            os.utime(consts.MDADM_PATH)
        os.chmod(consts.MDADM_PATH, mode=0o666)
        os.chown(consts.MDADM_PATH, sspl_uid, -1)
 def validate(self):
     # Common validator classes to check Cortx/system wide validator
     if not os.path.exists(self.SSPL_CONFIGURED):
         error = "SSPL is not configured. Run provisioner scripts in %s" % (
             self._script_dir)
         syslog.openlog(logoption=syslog.LOG_PID,
                        facility=syslog.LOG_LOCAL3)
         syslog.syslog(syslog.LOG_ERR, error)
         logger.error(error)
         raise SetupError(1, "%s - validation failure. %s", self.name,
                          error)
     # Validate required services are running
     retry = 3
     while retry > 0:
         try:
             ServiceV().validate('isrunning', self.services)
         except VError:
             retry -= 1
             time.sleep(5)
         else:
             break
     ServiceV().validate('isrunning', self.services)
     logger.info("%s - Validation done" % self.name)
    def validate(self):
        """Check for below requirement.

        1. Validate if sspl-ll user exists
        2. Validate input keys
        """
        # Check sspl-ll user exists
        sspl_uid = Utility.get_uid(self.user)
        if sspl_uid == -1:
            msg = "User %s doesn't exist. Please add user." % self.user
            logger.error(msg)
            raise SetupError(errno.EINVAL, msg)
        # Check input/provisioner configs
        machine_id = Utility.get_machine_id()
        cluster_id = Utility.get_config_value(
            consts.PRVSNR_CONFIG_INDEX,
            "server_node>%s>cluster_id" % machine_id)
        Utility.get_config_value(consts.PRVSNR_CONFIG_INDEX,
                                 "cluster>%s>name" % cluster_id)
        Utility.get_config_value(consts.PRVSNR_CONFIG_INDEX,
                                 "cluster>%s>site_count" % cluster_id)
        storage_set_count = int(
            Utility.get_config_value(
                consts.PRVSNR_CONFIG_INDEX,
                "cluster>%s>site>storage_set_count" % cluster_id))
        for i in range(storage_set_count):
            Utility.get_config_value(
                consts.PRVSNR_CONFIG_INDEX,
                "cluster>%s>storage_set[%s]>name" % (cluster_id, i))
            Utility.get_config_value(
                consts.PRVSNR_CONFIG_INDEX,
                "cluster>%s>storage_set[%s]>server_nodes" % (cluster_id, i))
            Utility.get_config_value(
                consts.PRVSNR_CONFIG_INDEX,
                "cluster>%s>storage_set[%s]>storage_enclosures" %
                (cluster_id, i))
Exemple #20
0
    def process(self):
        """Run test using user requested test plan."""
        self.plan = self.args.plan[0]

        # if self.plan is other than "self"
        # then only config change and service restart is required.
        if self.plan not in IVT_TEST_PLANS:
            # Take back up of sspl test config
            sspl_test_backup = '/etc/sspl_tests.conf.back'
            shutil.copyfile(sspl_test_file_path, sspl_test_backup)

            # Add global config in sspl_test config and revert the changes once
            # test completes. Global config path in sspl_tests.conf will be
            # referred by sspl_tests later
            sspl_global_config_url = Conf.get(
                SSPL_CONFIG_INDEX, "SYSTEM_INFORMATION>global_config_copy_url")
            Conf.set(SSPL_CONFIG_INDEX,
                     "SYSTEM_INFORMATION>global_config_copy_url",
                     self.sspl_test_gc_copy_url)
            Conf.save(SSPL_CONFIG_INDEX)

            # Enable & disable sensors based on environment
            update_sensor_info(SSPL_TEST_CONFIG_INDEX, self.node_type,
                               self.enclosure_type)

            # TODO: Move lines 99-131 & 152-159 to RunQATest class
            # Create dummy service and add service name in /etc/sspl.conf
            service_name = "dummy_service.service"
            service_file_path_src = \
                f"{TEST_DIR}/alerts/os/dummy_service_files/dummy_service.service"
            service_executable_code_src = \
                f"{TEST_DIR}/alerts/os/dummy_service_files/dummy_service.py"
            service_file_path_des = "/etc/systemd/system"
            service_executable_code_des = "/var/cortx/sspl/test"

            os.makedirs(service_executable_code_des, 0o777, exist_ok=True)

            shutil.copy(service_executable_code_src,
                        f'{service_executable_code_des}/dummy_service.py')
            # Make service file executable.
            cmd = f"chmod +x {service_executable_code_des}/dummy_service.py"
            _, error, returncode = SimpleProcess(cmd).run()
            if returncode != 0:
                logger.error("%s error occurred while executing cmd: %s" %
                             (error, cmd))
                logger.error("failed to assign execute permission for"
                             "dummy_service.py. dummy_service will fail.")

            # Copy service file to /etc/systemd/system/ path.
            shutil.copyfile(service_file_path_src,
                            f'{service_file_path_des}/dummy_service.service')
            cmd = "systemctl daemon-reload"
            _, error, returncode = SimpleProcess(cmd).run()
            if returncode != 0:
                logger.error(f"failed to execute '{cmd}',"
                             "systemctl will be unable to manage the"
                             f"dummy_service.service \n Error: {error}")

            self.dbus_service.enable(service_name)
            self.dbus_service.start(service_name)

            service_list = Conf.get(SSPL_CONFIG_INDEX,
                                    "SERVICEMONITOR>monitored_services")
            service_list.append(service_name)
            Conf.set(SSPL_CONFIG_INDEX, "SERVICEMONITOR>monitored_services",
                     service_list)

            threshold_inactive_time_original = Conf.get(
                SSPL_CONFIG_INDEX, "SERVICEMONITOR>threshold_inactive_time")
            threshold_inactive_time_new = 30
            Conf.set(SSPL_CONFIG_INDEX,
                     "SERVICEMONITOR>threshold_inactive_time",
                     threshold_inactive_time_new)
            Conf.save(SSPL_CONFIG_INDEX)

            cpu_usage_alert_wait = Conf.get(
                SSPL_CONFIG_INDEX,
                "NODEDATAMSGHANDLER>high_cpu_usage_wait_threshold")
            memory_usage_alert_wait = Conf.get(
                SSPL_CONFIG_INDEX,
                "NODEDATAMSGHANDLER>high_memory_usage_wait_threshold")

            cpu_usage_alert_wait_new = 10
            memory_usage_alert_wait_new = 20

            Conf.set(SSPL_CONFIG_INDEX,
                     "NODEDATAMSGHANDLER>high_cpu_usage_wait_threshold",
                     cpu_usage_alert_wait_new)
            Conf.set(SSPL_CONFIG_INDEX,
                     "NODEDATAMSGHANDLER>high_memory_usage_wait_threshold",
                     memory_usage_alert_wait_new)
            Conf.save(SSPL_CONFIG_INDEX)

            # TODO: Convert shell script to python
            # from cortx.sspl.sspl_test.run_qa_test import RunQATest
            # RunQATest(self.plan, self.coverage_enabled).run()
            CMD = "%s/run_qa_test.sh --plan %s --coverage %s"\
                   %(TEST_DIR, self.plan, self.coverage_enabled)
            try:
                _, error, rc = SimpleProcess(CMD).run(realtime_output=True)
            except KeyboardInterrupt:
                rc = 1
                error = "KeyboardInterrupt occurred while executing sspl test."
                logger.error("%s - ERROR: %s - CMD %s" %
                             (self.name, error, CMD))
            # Restore the original path/file & service, then throw exception
            # if execution is failed.
            service_list.remove(service_name)
            Conf.set(SSPL_CONFIG_INDEX, "SERVICEMONITOR>monitored_services",
                     service_list)
            Conf.set(SSPL_CONFIG_INDEX,
                     "SERVICEMONITOR>threshold_inactive_time",
                     threshold_inactive_time_original)
            Conf.set(SSPL_CONFIG_INDEX,
                     "SYSTEM_INFORMATION>global_config_copy_url",
                     sspl_global_config_url)
            Conf.set(SSPL_CONFIG_INDEX,
                     "NODEDATAMSGHANDLER>high_cpu_usage_wait_threshold",
                     cpu_usage_alert_wait)
            Conf.set(SSPL_CONFIG_INDEX,
                     "NODEDATAMSGHANDLER>high_memory_usage_wait_threshold",
                     memory_usage_alert_wait)
            Conf.save(SSPL_CONFIG_INDEX)
            shutil.copyfile(sspl_test_backup, sspl_test_file_path)
            if rc != 0:
                raise TestException("%s - ERROR: %s - CMD %s" %
                                    (self.name, error, CMD))

            print('Restarting the SSPL service..')
            CMD = "systemctl restart sspl-ll"
            try:
                SimpleProcess(CMD).run(realtime_output=True)
            except Exception as error:
                raise TestException(
                    "Error occurred while executing sspl tests: %s" % error)
        elif self.plan in NOT_IMPLEMENTED_TEST_PLANS:
            print("Tests skipped, test plan %s not applicable for SSPL." %
                  (self.plan))
            return 0
        else:
            # TODO: Convert shell script to python
            # from cortx.sspl.sspl_test.run_qa_test import RunQATest
            # RunQATest(self.plan).run()
            try:
                CMD = "%s/run_qa_test.sh --plan %s" % (TEST_DIR, self.plan)
                _, error, returncode = SimpleProcess(CMD).run(
                    realtime_output=True)
            except KeyboardInterrupt:
                msg = "KeyboardInterrupt occurred while executing sspl test."
                logger.error(msg)
                raise TestException(msg)
            except Exception as error:
                msg = "Error occurred while executing self test: %s" % error
                logger.error(msg)
                raise TestException(msg)
 def validate(self):
     if not self.args.config:
         msg = "%s - Argument validation failure. %s" % (
             self.name, "Global config is required.")
         logger.error(msg)
         raise SetupError(errno.EINVAL, msg)
    def cleanup_log_and_config():
        """--pre-factory cleanup : Cleanup logs, config files and
        undo everything whatever was done in post-install Mini-Provisioner
        Interface."""
        Conf.load(SSPL_CONFIG_INDEX, sspl_config_path)
        sspl_log_file_path = Utility.get_config_value(
            SSPL_CONFIG_INDEX, "SYSTEM_INFORMATION>sspl_log_file_path")
        iem_log_file_path = Utility.get_config_value(
            SSPL_CONFIG_INDEX, "IEMSENSOR>log_file_path")
        message_types = [
            Utility.get_config_value(SSPL_CONFIG_INDEX, "INGRESSPROCESSOR>message_type"),
            Utility.get_config_value(SSPL_CONFIG_INDEX, "EGRESSPROCESSOR>message_type")]

        # Directories and file which needs to deleted.
        directories = [
            f'/var/{PRODUCT_FAMILY}/sspl', f'/var/{PRODUCT_FAMILY}/iem/',
            f'/var/log/{PRODUCT_FAMILY}/sspl/', f'/var/log/{PRODUCT_FAMILY}/iem/',
            '/etc/sspl-ll/', f'{PRODUCT_BASE_DIR}/iem/iec_mapping']

        sspl_sudoers_file = '/etc/sudoers.d/sspl'
        sspl_dbus_policy_rules = '/etc/polkit-1/rules.d/sspl-ll_dbus_policy.rules'
        sspl_dbus_policy_conf = '/etc/dbus-1/system.d/sspl-ll_dbus_policy.conf'
        sspl_service_file = '/etc/systemd/system/sspl-ll.service'
        sspl_test_backup = '/etc/sspl_tests.conf.back'
        sspl_test_file_path = '/etc/sspl_test_gc_url.yaml'
        sspl_sb_log_file_path = sspl_log_file_path.replace(
            "/sspl.log", "/sspl_support_bundle.log")
        manifest_log_file_path = sspl_log_file_path.replace(
            "/sspl.log", "/manifest.log")

        # symlinks created during post_install
        sspl_ll_cli = "/usr/bin/sspl_ll_cli"

        # Remove SSPL config other config/log files which were
        # created during post_install.
        for filepath in [
                sspl_ll_cli, sspl_test_backup, sspl_test_file_path,
                file_store_config_path, global_config_file_path,
                sspl_log_file_path, iem_log_file_path, sspl_sb_log_file_path,
                manifest_log_file_path, RSYSLOG_IEM_CONF, IEM_LOGROTATE_CONF,
                sspl_dbus_policy_conf, sspl_dbus_policy_rules,
                sspl_sudoers_file, sspl_service_file]:
            FileStore().delete(filepath)

        # Delete directories which were created during post_install.
        for directory in directories:
            FileStore().delete(directory)
        logger.info("Deleted config/log files and directories.")

        # Delete sspl-ll user
        usernames = [x[0] for x in pwd.getpwall()]
        if USER in usernames:
            _, err, rc = SimpleProcess("/usr/sbin/userdel -f %s" % USER).run()
            if rc != 0:
                logger.info("Error occurref while deleteing %s user. ERROR: %s"
                    %(USER, err))
            else:
                logger.info("Deleted %s user." % USER)

        # Delete topic
        mbadmin = MessageBusAdmin(admin_id="admin")
        try:
            mbadmin.deregister_message_type(message_types)
            logger.info("Delete kafka %s topics." % message_types)
        except MessageBusError as e:
            logger.error(f"MessageBusError occurred while deleting topic:{e}")