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()
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])
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 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): """Check below requirements. 1. Validate input configs 2. Validate BMC connectivity 3. Validate storage controller connectivity 4. Validate network interface availability """ machine_id = Utility.get_machine_id() mgmt_interfaces = [] data_private_interfaces = [] data_public_interfaces = [] # Validate input/provisioner configs node_type = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "server_node>%s>type" % machine_id) cluster_id = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "server_node>%s>cluster_id" % machine_id) if node_type.lower() not in ["virtual", "vm"]: bmc_ip = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "server_node>%s>bmc>ip" % machine_id) bmc_user = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "server_node>%s>bmc>user" % machine_id) bmc_secret = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "server_node>%s>bmc>secret" % machine_id) bmc_key = Cipher.generate_key(machine_id, ServiceTypes.SERVER_NODE.value) bmc_passwd = Cipher.decrypt( bmc_key, bmc_secret.encode("utf-8")).decode("utf-8") data_private_interfaces = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "server_node>%s>network>data>private_interfaces" % machine_id) data_public_interfaces = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "server_node>%s>network>data>public_interfaces" % machine_id) mgmt_public_fqdn = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "server_node>%s>network>management>public_fqdn" % machine_id) mgmt_interfaces = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "server_node>%s>network>management>interfaces" % machine_id) data_private_fqdn = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "server_node>%s>network>data>private_fqdn" % machine_id) data_public_fqdn = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "server_node>%s>network>data>public_fqdn" % machine_id) enclosure_id = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "server_node>%s>storage>enclosure_id" % machine_id) primary_ip = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "storage_enclosure>%s>controller>primary>ip" % enclosure_id) secondary_ip = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "storage_enclosure>%s>controller>secondary>ip" % enclosure_id) cntrlr_user = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "storage_enclosure>%s>controller>user" % enclosure_id) cntrlr_secret = Utility.get_config_value( PRVSNR_CONFIG_INDEX, "storage_enclosure>%s>controller>secret" % enclosure_id) cntrlr_key = Cipher.generate_key(enclosure_id, ServiceTypes.STORAGE_ENCLOSURE.value) cntrlr_passwd = Cipher.decrypt( cntrlr_key, cntrlr_secret.encode("utf-8")).decode("utf-8") # Validate BMC connectivity & storage controller accessibility if node_type.lower() not in ["virtual", "vm"]: NetworkV().validate("connectivity", [bmc_ip, primary_ip, secondary_ip]) BmcV().validate("accessible", [socket.getfqdn(), bmc_ip, bmc_user, bmc_passwd]) c_validator = ControllerV() c_validator.validate("accessible", [primary_ip, cntrlr_user, cntrlr_passwd]) c_validator.validate("accessible", [secondary_ip, cntrlr_user, cntrlr_passwd]) # Validate network fqdn reachability NetworkV().validate( "connectivity", [mgmt_public_fqdn, data_private_fqdn, data_public_fqdn]) # Validate network interface availability for i_list in [ mgmt_interfaces, data_private_interfaces, data_public_interfaces ]: self.validate_nw_cable_connection(i_list) self.validate_nw_interfaces(i_list)
def configure_sspl_syslog(self): """Configure log file path in rsyslog and update logrotate config file.""" system_files_root = "%s/low-level/files" % consts.SSPL_BASE_DIR sspl_log_file_path = Utility.get_config_value(consts.SSPL_CONFIG_INDEX, "SYSTEM_INFORMATION>sspl_log_file_path") sspl_sb_log_file_path = sspl_log_file_path.replace("/sspl.log","/sspl_support_bundle.log") iem_log_file_path = Utility.get_config_value(consts.SSPL_CONFIG_INDEX, "IEMSENSOR>log_file_path") manifest_log_file_path = sspl_log_file_path.replace("/sspl.log","/manifest.log") # IEM configuration os.makedirs("%s/iem/iec_mapping" % consts.PRODUCT_BASE_DIR, exist_ok=True) distutils.dir_util.copy_tree("%s/iec_mapping/" % system_files_root, "%s/iem/iec_mapping" % consts.PRODUCT_BASE_DIR) if not os.path.exists(consts.RSYSLOG_IEM_CONF): shutil.copyfile("%s/%s" % (system_files_root, consts.RSYSLOG_IEM_CONF), consts.RSYSLOG_IEM_CONF) # Update log location as per sspl.conf Utility.replace_expr(consts.RSYSLOG_IEM_CONF, 'File.*[=,"]', 'File="%s"' % iem_log_file_path) # SSPL rsys log configuration if not os.path.exists(consts.RSYSLOG_SSPL_CONF): shutil.copyfile("%s/%s" % (system_files_root, consts.RSYSLOG_SSPL_CONF), consts.RSYSLOG_SSPL_CONF) # Update log location as per sspl.conf Utility.replace_expr(consts.RSYSLOG_SSPL_CONF, 'File.*[=,"]', 'File="%s"' % sspl_log_file_path) # Manifest Bundle log configuration if not os.path.exists(consts.RSYSLOG_MSB_CONF): shutil.copyfile("%s/%s" % (system_files_root, consts.RSYSLOG_MSB_CONF), consts.RSYSLOG_MSB_CONF) # Update log location as per sspl.conf Utility.replace_expr(consts.RSYSLOG_MSB_CONF, 'File.*[=,"]', 'File="%s"' % manifest_log_file_path) # Support Bundle log configuration if not os.path.exists(consts.RSYSLOG_SB_CONF): shutil.copyfile("%s/%s" % (system_files_root, consts.RSYSLOG_SB_CONF), consts.RSYSLOG_SB_CONF) # Update log location as per sspl.conf Utility.replace_expr(consts.RSYSLOG_SB_CONF, 'File.*[=,"]', 'File="%s"' % sspl_sb_log_file_path) # Configure logrotate # Create logrotate dir in case it's not present os.makedirs(consts.LOGROTATE_DIR, exist_ok=True) Utility.replace_expr("%s/etc/logrotate.d/iem_messages" % system_files_root, 0, iem_log_file_path) Utility.replace_expr("%s/etc/logrotate.d/sspl_logs" % system_files_root, 0, sspl_log_file_path) Utility.replace_expr("%s/etc/logrotate.d/sspl_sb_logs" % system_files_root, 0, sspl_sb_log_file_path) shutil.copy2("%s/etc/logrotate.d/iem_messages" % system_files_root, consts.IEM_LOGROTATE_CONF) shutil.copy2("%s/etc/logrotate.d/sspl_logs" % system_files_root, consts.SSPL_LOGROTATE_CONF) shutil.copy2("%s/etc/logrotate.d/manifest_logs" % system_files_root, consts.MSB_LOGROTATE_CONF) shutil.copy2("%s/etc/logrotate.d/sspl_sb_logs" % system_files_root, consts.SB_LOGROTATE_CONF) # This rsyslog restart will happen after successful updation of rsyslog # conf file and before sspl starts. If at all this will be removed from # here, there will be a chance that SSPL intial logs will not be present in # "/var/log/<product>/sspl/sspl.log" file. So, initial logs needs to be collected from # "/var/log/messages" service = DbusServiceHandler() service.restart('rsyslog.service')
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))
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}")