async def receive(request): Log.debug(f"Received GET request for component " \ f"{request.rel_url.query['component']}") try: component = request.rel_url.query['component'] EventMessage.subscribe(component=component) alert = EventMessage.receive() except EventMessageError as e: status_code = e.rc error_message = e.desc Log.error(f"Unable to receive event message for component: " \ f"{component}, status code: {status_code}," \ f" error: {error_message}") response_obj = {'error_code': status_code, 'exception': \ ['EventMessageError', {'message': error_message}]} except Exception as e: exception_key = type(e).__name__ exception = RestServerError(exception_key).http_error() status_code = exception[0] error_message = exception[1] Log.error(f"Internal error while receiving event messages for " \ f"component: {component}, status code: " \ f"{status_code}, error: {error_message}") response_obj = {'error_code': status_code, 'exception': \ [exception_key, {'message': error_message}]} raise EventMessageError(status_code, error_message) from e else: status_code = 200 # No exception, Success response_obj = {'alert': alert} Log.debug(f"GET method finished with status code: {status_code}" \ f"for component {component} and received event message " \ f"alert info. - {alert['iem']['info']}.") finally: return web.Response(text=json.dumps(response_obj), \ status=status_code)
def run_cmd(self, cmd, check_error=True): """ Run command and throw error if cmd failed Args: cmd ([string]): Command to execute on system. Raises: Exception: raise command failed exception. HACommandTerminated: Command termineted exception Returns: string: Command output. """ try: _err = "" _proc = SimpleProcess(cmd) _output, _err, _rc = _proc.run(universal_newlines=True) Log.debug(f"cmd: {cmd}, output: {_output}, err: {_err}, rc: {_rc}") if _rc != 0 and check_error: Log.error( f"cmd: {cmd}, output: {_output}, err: {_err}, rc: {_rc}") raise Exception(f"Failed to execute {cmd}") return _output, _err, _rc except Exception as e: Log.error("Failed to execute %s Error: %s %s" % (cmd, e, _err)) raise HACommandTerminated("Failed to execute %s Error: %s %s" % (cmd, e, _err))
def __init__(self, rc=1, desc=None, message_id=HA_BASIC_ERROR, message_args=None): """ Parent class for the HA error classes """ super(HAError, self).__init__(rc=rc, desc=desc, message_id=message_id, message_args=message_args) Log.error(f"error({self._message_id}):rc({self._rc}):{self._desc}:{self._message_args}")
def _monitor_action(self, callback_ack, state, **args): """ Return action on status """ Log.debug(str(args)) if args[const.CURRENT_NODE_STATUS] == Action.FAILED and args[const.OTHER_NODE_STATUS] == Action.FAILED: return const.OCF_SUCCESS elif args[const.CURRENT_NODE_STATUS] == Action.FAILED: return const.OCF_ERR_GENERIC elif args[const.CURRENT_NODE_STATUS] == Action.OK: return const.OCF_SUCCESS elif args[const.CURRENT_NODE_STATUS] == Action.RESOLVED: Log.info(f"Ack for {args[const.FILENAME_KEY]} with key {args[const.PATH_KEY]}" f" node {args[const.CURRENT_NODE]}") return callback_ack(args[const.PATH_KEY]+'_'+args[const.CURRENT_NODE]) elif args[const.CURRENT_NODE_STATUS] == Action.RESTART: Log.info(f"Restart action taken for {args[const.FILENAME_KEY]} on {args[const.CURRENT_NODE]}") if state == const.STATE_START: return const.OCF_SUCCESS elif state == const.STATE_RUNNING: return const.OCF_ERR_GENERIC elif state == const.STATE_STOP: callback_ack(args[const.PATH_KEY]+'_'+args[const.CURRENT_NODE]) Log.info(f"Ack for {args[const.FILENAME_KEY]} with key {args[const.PATH_KEY]} " f" node {args[const.CURRENT_NODE]}") return Action.RESTART return const.OCF_SUCCESS else: Log.error(f"Unimplemented value for status {args[const.CURRENT_NODE_STATUS]}") return const.OCF_ERR_UNIMPLEMENTED
def main(resource: DynamicFidServiceRA, action: str = '') -> int: """ Main function acts as switch case for DynamicFidServiceRA resource agent. Args: resource (DynamicFidServiceRA): Resource agent action (str): Resource agent action called by Pacemaker. Defaults to ''. Returns: int: Provide output as int code provided by pacemaker. """ try: if action == "meta-data": return resource.metadata() ConfigManager.init("resource_agent") Log.debug(f"{resource} initialized for action {action}") if action == "monitor": return resource_agent.monitor() elif action == "start": return resource_agent.start() elif action == "stop": return resource_agent.stop() else: print(f"Usage {sys.argv[0]} [monitor] [start] [stop] [meta-data]") exit(0) except Exception as e: Log.error( f"systemd_fid_wrapper_ra failed to perform {action}. Error: {e}") return const.OCF_ERR_GENERIC
def remove_node(self, node): """ Remove node from pcs cluster """ # TODO: Limitation for node remove (in cluster node cannot remove it self) # Check if node already removed _output, _err, _rc = self._execute.run_cmd(const.PCS_STATUS) Log.info( f"Cluster status output before remove node: {_output}, {_err}, {_rc}" ) _rc, status = self.node_status(node) if _rc != 1: self._execute.run_cmd(f"pcs cluster node remove {node} --force") _rc, status = self.node_status(node) Log.debug(f"For node {node} status: {status}, rc: {_rc}") if _rc != 1: Log.error(f"Failed to remove {node}") raise Exception(f"Failed to remove {node}") else: Log.info(f"Node {node} removed from cluster") else: Log.info(f"Node {node} already removed from cluster") _output, _err, _rc = self._execute.run_cmd(const.PCS_STATUS) Log.info( f"Cluster status output after remove node: {_output}, {_err}, {_rc}" )
def addattribute(conn, dn, attr_to_add, value): mod_attrs = [(ldap.MOD_ADD, attr_to_add, bytes(str(value), 'utf-8'))] try: conn.modify_s(dn, mod_attrs) except Exception: Log.error('Exception while adding '+ attr_to_add + ' to dn '+ dn) raise Exception('Exception while adding '+ attr_to_add + ' to dn '+ dn)
def read_ldap_credentials(self): """Read ldap credentials (rootdn, sgiam) from the openldap_config file.""" try: # Load the openldap config file index_id = 'openldap_config_file_read_index' Conf.load(index_id, f'yaml://{self.openldap_config_file}') # Read the cluster id from openldap_config file self.cluster_id = Conf.get(index_id, f'{self.cluster_id_key}') cipher_key = Cipher.generate_key( self.cluster_id, self.get_confkey('CONFSTORE_OPENLDAP_CONST_KEY')) # rootdn username/password self.ldap_root_user = Conf.get(index_id, f'{self.rootdn_user_key}') encrypted_rootdn_pass = Conf.get(index_id, f'{self.rootdn_pass_key}') if encrypted_rootdn_pass != None: self.rootdn_passwd = Cipher.decrypt( cipher_key, bytes(str(encrypted_rootdn_pass), 'utf-8')) except Exception as e: Log.error(f'read ldap credentials failed, error: {e}') raise e
def update_ldap_credentials(self): """Update ldap credentials (rootdn, sgiam) to openldap_config file.""" try: # Load the openldap config file index_id = 'openldap_config_file_write_index' Conf.load(index_id, f'yaml://{self.openldap_config_file}') # get the rootdn credentials from provisoner config file # set the rootdn credentials in to openldap_config file ldap_root_user = self.get_confvalue( self.get_confkey('CONFIG>CONFSTORE_ROOTDN_USER_KEY')) encrypted_rootdn_pass = self.get_confvalue( self.get_confkey('CONFIG>CONFSTORE_ROOTDN_PASSWD_KEY')) if encrypted_rootdn_pass is None: Log.error('rootdn password cannot be None.') raise Exception('rootdn password cannot be None.') Conf.set(index_id, f'{self.rootdn_user_key}', f'{ldap_root_user}') Conf.set(index_id, f'{self.rootdn_pass_key}', f'{encrypted_rootdn_pass}') # save openldap config file Conf.save(index_id) except Exception as e: Log.error(f'update rootdn credentials failed, error: {e}') raise Exception(f'update rootdn credentials failed, error: {e}')
def register_message_type(self, admin_id: str, message_types: list, \ partitions: int): """ Creates a list of message types. Parameters: admin_id A String that represents Admin client ID. message_types This is essentially equivalent to the list of queue/topic name. For e.g. ["Alert"] partitions Integer that represents number of partitions to be created. """ Log.debug(f"Register message type {message_types} using {admin_id}" \ f" with {partitions} partitions") admin = self._clients['admin'][admin_id] new_message_type = [NewTopic(each_message_type, \ num_partitions=partitions) for each_message_type in message_types] created_message_types = admin.create_topics(new_message_type) self._task_status(created_message_types, method='register_message_type') for each_message_type in message_types: for list_retry in range(1, self._max_list_message_type_count+2): if each_message_type not in \ list(self._get_metadata(admin).keys()): if list_retry > self._max_list_message_type_count: Log.error(f"MessageBusError: Timed out after retry " \ f"{list_retry} while creating message_type " \ f"{each_message_type}") raise MessageBusError(errno.ETIMEDOUT, "Timed out " +\ "after retry %d while creating message_type %s.", \ list_retry, each_message_type) time.sleep(list_retry*1) continue else: break
def init(cls, component: str, source: str, cluster_id: str, \ message_server_endpoints: str, **message_server_kwargs): """ Set the Event Message context Parameters: component Component that generates the IEM. For e.g. 'S3', 'SSPL' source Single character that indicates the type of component. For e.g. H-Hardware, S-Software, F-Firmware, O-OS """ cls._component = component cls._source = source cls._site_id = 1 cls._rack_id = 1 cls._node_id = Conf.machine_id cls._cluster_id = cluster_id if cls._component is None: Log.error("Invalid component type: %s" % cls._component ) raise EventMessageError(errno.EINVAL, "Invalid component type: %s", \ cls._component) if cls._source not in cls._SOURCE.keys(): Log.error("Invalid source type: %s" % cls._source) raise EventMessageError(errno.EINVAL, "Invalid source type: %s", \ cls._source) MessageBus.init(message_server_endpoints, **message_server_kwargs) cls._producer = MessageProducer(producer_id='event_producer', \ message_type='IEM', method='sync') Log.info("IEM Producer initialized for component %s and source %s" % \ (cls._component, cls._source))
def get_system_health( self, element: CLUSTER_ELEMENTS = CLUSTER_ELEMENTS.CLUSTER.value, depth: int = 1, **kwargs) -> json: """ Return health status for the requested elements. Args: element ([CLUSTER_ELEMENTS]): The element whose health status is to be returned. depth ([int]): A depth of elements starting from the input "element" that the health status is to be returned. **kwargs([dict]): Variable number of arguments that are used as filters, e.g. "id" of the input "element". Returns: ([dict]): Returns dictionary. {"status": "Succeeded"/"Failed"/"Partial", "output": "", "error": ""} status: Succeeded, Failed, Partial output: Dictionary with element health status error: Error information if the request "Failed" """ try: # Fetch the health status system_health_controller = SystemHealthController(self._confstore) return system_health_controller.get_status(component=element, depth=depth, version=self._version, **kwargs) except Exception as e: Log.error(f"Failed returning system health . Error: {e}") raise ClusterManagerError( "Failed returning system health, internal error")
def _validate_permissions(self) -> None: # confirm that user is root or part of haclient group" user = getpass.getuser() group_id = os.getgid() group_list = os.getgrouplist(user, group_id) try: # find group id for root and haclient id_ha = grp.getgrnam(const.USER_GROUP_HACLIENT) id_root = grp.getgrnam(const.USER_GROUP_ROOT) # if group not root or haclient return error if id_ha.gr_gid not in group_list and id_root.gr_gid not in group_list: Log.error( f"User {user} does not have necessary permissions to execute this CLI" ) raise HAInvalidPermission( f"User {user} does not have necessary permissions to execute this CLI" ) # TODO : Check if user needs to be changed to hauser except KeyError: Log.error("haclient group is not present on the system") raise HAInvalidPermission( "haclient group is not present on the system")
def main(action: str = '') -> int: """ Main function acts as switch case for IPHealthChecker resource agent. Args: action (str): Resource agent action called by Pacemaker. Defaults to ''. Returns: int: Provide output as int code provided by pacemaker. """ try: if action == "meta-data": return VipHealthMonitor.metadata() ConfigManager.init("resource_agent") resource_agent = VipHealthMonitor() Log.debug(f"{resource_agent} initialized for action {action}") if action == "monitor": return resource_agent.monitor() elif action == "start": return resource_agent.start() elif action == "stop": return resource_agent.stop() else: print(f"Usage {sys.argv[0]} [monitor] [start] [stop] [meta-data]") exit(0) except Exception as e: Log.error( f"vip health check failed to perform {action}. Error: {traceback.format_exc()} {e}" ) return const.OCF_ERR_GENERIC
async def _exc_components_cmd(commands: List, bundle_id: str, path: str, \ component: str, node_name: str, comment: str, config_url:str, services:str, binlogs:bool, coredumps:bool, stacktrace:bool, duration:str, size_limit:str): """ Executes the Command for Bundle Generation of Every Component. commands: Command of the component :type:str bundle_id: Unique Bundle ID of the generation process. :type:str path: Path to create the tar by components :type:str component: Name of Component to be executed :type: str node_name: Name of Node where the Command is being Executed :type:str comment: User Comment: type:str """ for command in commands: # SB Framework will not parse additional filters until all the components # accept filters in their respective support bundle scripts. cli_cmd = f"{command} -b {bundle_id} -t {path} -c {config_url}"\ f" -s {services} --duration {duration} --size_limit {size_limit}"\ f" --binlogs {binlogs} --coredumps {coredumps} --stacktrace {stacktrace}" Log.info(f"Executing command -> {cli_cmd}") cmd_proc = SimpleProcess(cli_cmd) output, err, return_code = cmd_proc.run() Log.debug(f"Command Output -> {output} {err}, {return_code}") if return_code != 0: Log.error(f"Command Output -> {output} {err}, {return_code}") else: Log.debug(f"Command Output -> {output} {err}, {return_code}") return component, return_code
def main(argv: list): try: if len(sys.argv) == 1: Cmd.usage("ha_setup") sys.exit(1) if sys.argv[1] == "cleanup": if not os.path.exists(const.HA_CONFIG_FILE): a_str = f'Cleanup can not be proceed as \ HA config file: {const.HA_CONFIG_FILE} \ is missing. Either cleanup is already done or there \ is some other problem' sys.stdout.write(a_str) return 0 ConfigManager.init("ha_setup") desc = "HA Setup command" command = Cmd.get_command(desc, argv[1:]) command.process() except Exception as err: Log.error("%s\n" % traceback.format_exc()) sys.stderr.write( f"Setup command:{argv[1]} failed for cortx-ha. Error: {err}\n") return errno.EINVAL
def _exc_components_cmd(commands: List, bundle_id: str, path: str, component: str, node_name: str, comment: str): """ Executes the Command for Bundle Generation of Every Component. :param commands: Command of the component :type:str :param bundle_id: Unique Bundle ID of the generation process. :type:str :param path: Path to create the tar by components :type:str :param component: Name of Component to be executed :type: str :param node_name:Name of Node where the Command is being Executed :type:str :param comment: :User Comment: type:str :return: """ for command in commands: Log.info(f"Executing command -> {command} {bundle_id} {path}") cmd_proc = SimpleProcess(f"{command} {bundle_id} {path}") output, err, return_code = cmd_proc.run() Log.debug(f"Command Output -> {output} {err}, {return_code}") if return_code != 0: Log.error(f"Command Output -> {output} {err}, {return_code}") ComponentsBundle._publish_log( f"Bundle generation failed for '{component}'", ERROR, bundle_id, node_name, comment) else: ComponentsBundle._publish_log( f"Bundle generation started for '{component}'", INFO, bundle_id, node_name, comment)
def validate_permissions(self) -> None: # confirm that user is root or part of haclient group" user = getpass.getuser() group_id = os.getgid() try: # find group id for root and haclient id_ha = grp.getgrnam(const.USER_GROUP_HACLIENT) id_root = grp.getgrnam(const.USER_GROUP_ROOT) # if group not root or haclient return error if group_id != id_ha.gr_gid and group_id != id_root.gr_gid: Log.error( f"User {user} does not have necessary permissions to execute this CLI" ) raise HAInvalidPermission( f"User {user} does not have necessary permissions to execute this CLI" ) # The user name "hauser"; which is part of the "haclient" group; # is used by HA. # internal commands are allowed only if the user is "hauser" # As of now, every HA CLI will be internal command. So, we # do not need this change. We can revisit this if needed in future #if user == const.USER_HA_INTERNAL: # self._is_hauser = True # TBD : If required raise seperate exception for root and haclient except KeyError: Log.error("Group root / haclient is not defined") raise HAInvalidPermission("Group root / haclient is not defined ")
async def get_bundle_status(command): """ Initializes the process for Displaying the Status for Support Bundle. :param command: Csm_cli Command Object :type: command :return: None """ try: bundle_id = command.options.get(const.SB_BUNDLE_ID) conf = GeneralConfig(database.DATABASE) db = DataBaseProvider(conf) repo = SupportBundleRepository(db) all_nodes_status = await repo.retrieve_all(bundle_id) response = { "status": [ each_status.to_primitive() for each_status in all_nodes_status ] } return Response(output=response, rc=OPERATION_SUCESSFUL) except DataAccessExternalError as e: Log.warn(f"Failed to connect to elasticsearch: {e}") return Response( output=("Support Bundle status is not available currently" " as required services are not running." " Please wait and check the /tmp/support_bundle" " folder for newly generated support bundle."), rc=str(errno.ECONNREFUSED)) except Exception as e: Log.error(f"Failed to get bundle status: {e}") return Response( output=("Support Bundle status is not available currently" " as required services are not running." " Failed to get status of bundle."), rc=str(errno.ENOENT))
def get_status_raw(self, component: str, component_id: str = None, **kwargs): """ get status method. This is a generic method which can return status of any component(s). """ status = None try: # Prepare key and read the health value. if component_id != None: key = ElementHealthEvaluator.prepare_key(component, comp_id=component_id, **kwargs) status = self.healthmanager.get_key(key) else: key = ElementHealthEvaluator.prepare_key(component, **kwargs) status = self.healthmanager.get_key(key, just_value=False) # Remove any keys which are not for the health status. ignore_keys = [] for key in status: if "health" not in key: ignore_keys.append(key) for key in ignore_keys: del status[key] return status except Exception as e: Log.error( f"Failed reading status for component: {component} with Error: {e}" ) raise HaSystemHealthException("Failed reading status")
def cleanup(forceclean): # Removing schemas filelist = glob.glob( '/etc/openldap/slapd.d/cn=config/cn=schema/*ppolicy.ldif') for policyfile in filelist: BaseConfig.safe_remove(policyfile) module_files = [ "cn=module{0}.ldif", "cn=module{1}.ldif", "cn=module{2}.ldif" ] for module_file in module_files: module_file = '/etc/openldap/slapd.d/cn=config/' + str(module_file) BaseConfig.safe_remove(module_file) mdb_directory = '/etc/openldap/slapd.d/cn=config/olcDatabase={2}mdb' try: files = glob.glob( '/etc/openldap/slapd.d/cn=config/olcDatabase={2}mdb/*') for f in files: BaseConfig.safe_remove(f) except Exception: Log.error('Error while deleting ' + mdb_directory) mdbfile = '/etc/openldap/slapd.d/cn=config/olcDatabase={2}mdb.ldif' BaseConfig.safe_remove(mdbfile) #Data Cleanup if forceclean == 'True': files = glob.glob('/var/lib/ldap/*') for f in files: BaseConfig.safe_remove(f) #Clear the password set in config conn = ldap.initialize("ldapi:///") conn.sasl_non_interactive_bind_s('EXTERNAL') Replication.deleteattribute(conn, "olcDatabase={0}config,cn=config", "olcRootPW") conn.unbind_s()
def get_hierarchy(component: str) -> dict: """ This method returns a component health update hierarchy. """ try: if component in SystemHealthHierarchy._server_hw: return SystemHealthHierarchy._server_hw[ SystemHealthHierarchy._server_hw.index(component):] elif component in SystemHealthHierarchy._server_service: return SystemHealthHierarchy._server_service[ SystemHealthHierarchy._server_service.index(component):] elif component in SystemHealthHierarchy._storage: return SystemHealthHierarchy._storage[ SystemHealthHierarchy._storage.index(component):] else: Log.error( f"Health update hierarchy not present for component: {component}" ) raise HaSystemHealthHierarchyException( "Health update hierarchy not present for the component") except Exception as e: Log.error( f"Failed to get health update hierarchy for component with Error: {e}" ) raise HaSystemHealthHierarchyException( "Failed to get health update hierarchy")
def main(resource, action=''): try: if action == 'meta-data': return resource.metadata() Conf.load(const.HA_GLOBAL_INDEX, Yaml(const.HA_CONFIG_FILE)) log_path = Conf.get(const.HA_GLOBAL_INDEX, f"LOG{_DELIM}path") log_level = Conf.get(const.HA_GLOBAL_INDEX, f"LOG{_DELIM}level") Log.init(service_name='resource_agent', log_path=log_path, level=log_level) with open(const.RESOURCE_SCHEMA, 'r') as f: resource_schema = json.load(f) os.makedirs(const.RA_LOG_DIR, exist_ok=True) resource_agent = resource(DecisionMonitor(), resource_schema) Log.debug(f"{resource_agent} initialized for action {action}") if action == 'monitor': return resource_agent.monitor() elif action == 'start': return resource_agent.start() elif action == 'stop': return resource_agent.stop() else: print('Usage %s [monitor] [start] [stop] [meta-data]' % sys.argv[0]) exit() except Exception as e: Log.error(f"{traceback.format_exc()}") return const.OCF_ERR_GENERIC
def deleteattribute(conn, dn, attr_to_delete): mod_attrs = [(ldap.MOD_DELETE, attr_to_delete, None)] try: conn.modify_s(dn, mod_attrs) except Exception: Log.error('Exception while deleting ' + attr_to_delete + ' from dn ' + dn)
def publish(self, event: RecoveryActionEvent) -> None: """ Publish event. Args: event (RecoveryActionEvent): Action event. """ try: #TODO: Use Transactional producer in future. component_list = [] # Run through list of components subscribed for this event and send event to each of them component_list_key = EVENT_MANAGER_KEYS.EVENT_KEY.value.replace( "<resource>", event.resource_type).replace("<state>", event.event_type) component_list_key_val = self._confstore.get(component_list_key) if component_list_key_val: _, value = component_list_key_val.popitem() component_list = json.loads(value) for component in component_list: message_producer = self._get_producer(component) event_to_send = str(event) Log.info( f"Sending action event {event_to_send} to component {component}" ) message_producer.publish(event_to_send) except Exception as e: Log.error( f"Failed sending message for {event.resource_type}, Error: {e}" ) raise PublishException( f"Failed sending message for {event.resource_type}, Error: {e}" )
def deregister_message_type(self, admin_id: str, message_types: list): """ Deletes a list of message types. Parameters: admin_id A String that represents Admin client ID. message_types This is essentially equivalent to the list of queue/topic name. For e.g. ["Alert"] """ Log.debug(f"Deregister message type {message_types} using {admin_id}") admin = self._clients['admin'][admin_id] deleted_message_types = admin.delete_topics(message_types) self._task_status(deleted_message_types,\ method='deregister_message_type') for each_message_type in message_types: for list_retry in range(1, self._max_list_message_type_count + 2): if each_message_type in list(self._get_metadata(admin).keys()): if list_retry > self._max_list_message_type_count: Log.error(f"MessageBusError: Timed out after "\ f"{list_retry} retry to delete message_type "\ f"{each_message_type}") raise MessageBusError(errno.ETIMEDOUT,\ "Timed out after %d retry to delete message_type" +\ "%s.", list_retry, each_message_type) time.sleep(list_retry * 1) continue else: break
def __init__(self): """ Initialize a MessageBus and load its configurations """ Conf.load('config_file', 'json:///etc/cortx/cortx.conf', skip_reload=True) # if Log.logger is already initialized by some parent process # the same file will be used to log all the messagebus related # logs, else standard message_bus.log will be used. if not Log.logger: log_level = Conf.get('config_file', 'utils>log_level', 'INFO') Log.init('message_bus', '/var/log/cortx/utils/message_bus', \ level=log_level, backup_count=5, file_size_in_mb=5) try: Conf.load('message_bus', self.conf_file, skip_reload=True) self._broker_conf = Conf.get('message_bus', 'message_broker') broker_type = self._broker_conf['type'] Log.info(f"MessageBus initialized as {broker_type}") except ConfError as e: Log.error(f"MessageBusError: {e.rc} Error while parsing" \ f" configuration file {self.conf_file}. {e}.") raise MessageBusError(e.rc, "Error while parsing " + \ "configuration file %s. %s.", self.conf_file, e) except Exception as e: Log.error(f"MessageBusError: {e.rc} Error while parsing" \ f" configuration file {self.conf_file}. {e}.") raise MessageBusError(errno.ENOENT, "Error while parsing " + \ "configuration file %s. %s.", self.conf_file, e) self._broker = MessageBrokerFactory.get_instance(broker_type, \ self._broker_conf)
def send(self, producer_id: str, message_type: str, method: str,\ messages: list, timeout=0.1): """ Sends list of messages to Kafka cluster(s). Parameters: producer_id A String that represents Producer client ID. message_type This is essentially equivalent to the queue/topic name. For e.g. "Alert" method Can be set to "sync" or "async"(default). messages A list of messages sent to Kafka Message Server """ Log.debug(f"Producer {producer_id} sending list of messages "\ f"{messages} of message type {message_type} to kafka server"\ f" with method {method}") producer = self._clients['producer'][producer_id] if producer is None: Log.error(f"MessageBusError: "\ f"{errors.ERR_SERVICE_NOT_INITIALIZED}. Producer: "\ f"{producer_id} is not initialized") raise MessageBusError(errors.ERR_SERVICE_NOT_INITIALIZED,\ "Producer %s is not initialized", producer_id) for message in messages: producer.produce(message_type, bytes(message, 'utf-8'),\ callback=self.delivery_callback) if method == 'sync': producer.flush() else: producer.poll(timeout=timeout) Log.debug("Successfully Sent list of messages to Kafka cluster")
def post_install(self): """ Performs post install operations. Raises exception on error """ try: # Remove opendistro_security plugins. Elasticsearch.delete_path(self.opendistro_security_plugin) # Delete opendistro_security configuration entries from # elasticsearch.yml file. file_contents = Elasticsearch.read_file_contents( self.elasticsearch_config_path) flag = 1 start_line = "######## Start OpenDistro" end_line = "######## End OpenDistro" with open(self.elasticsearch_config_path, "w") as f: for line in file_contents: if line.startswith(start_line): flag = 0 if line.startswith(end_line): flag = 1 if flag and not line.startswith(end_line): f.write(line) f.close() except OSError as e: msg = f"Exception in in post_install {e}." Log.error(msg) raise Log.info("Post_install done.") return 0
def filter_event(self): """ Filter event based on Node, Resource and Fencing type. Args: msg (str): Msg """ ha_required_alert_module = None ha_required_alert_module_operation = None if self.crm_env is None: raise AlertEventFilterError(f"Identified empty events: {str(self.crm_env)}") try: alert_filter_module = self.crm_env["CRM_alert_kind"] alert_filter_module_operation = self.crm_env["CRM_alert_desc"] if alert_filter_module.lower() in self.alert_filter_modules.get(ALERTS.REQUIRED_COMPONENT): ha_required_alert_module = alert_filter_module if ha_required_alert_module and alert_filter_module_operation.lower() in self.alert_filter_module_operations.get( ha_required_alert_module): ha_required_alert_module_operation = alert_filter_module_operation return ha_required_alert_module, ha_required_alert_module_operation except Exception as e: Log.error(f"Error occurred in alert event filter: {str(e)}") return ha_required_alert_module, ha_required_alert_module_operation