async def distribute_function(self) -> str: """ Distributes an API call :return: Dictionary with API response """ try: request_type = rq.functions[self.input_json['function']]['type'] is_dapi_enabled = self.cluster_items['distributed_api']['enabled'] is_cluster_disabled = self.node == local_client and cluster.check_cluster_status( ) if 'wait_for_complete' not in self.input_json['arguments']: self.input_json['arguments']['wait_for_complete'] = False # if it is a cluster API request and the cluster is not enabled, raise an exception if is_cluster_disabled and 'cluster' in self.input_json['function'] and \ self.input_json['function'] != '/cluster/status' and \ self.input_json['function'] != '/cluster/config' and \ self.input_json['function'] != '/cluster/node': raise exception.WazuhException(3013) # First case: execute the request local. # If the distributed api is not enabled # If the cluster is disabled or the request type is local_any # if the request was made in the master node and the request type is local_master # if the request came forwarded from the master node and its type is distributed_master if not is_dapi_enabled or is_cluster_disabled or request_type == 'local_any' or \ (request_type == 'local_master' and self.node_info['type'] == 'master') or \ (request_type == 'distributed_master' and self.input_json['from_cluster']): return await self.execute_local_request() # Second case: forward the request # Only the master node will forward a request, and it will only be forwarded if its type is distributed_ # master elif request_type == 'distributed_master' and self.node_info[ 'type'] == 'master': return await self.forward_request() # Last case: execute the request remotely. # A request will only be executed remotely if it was made in a worker node and its type isn't local_any else: return await self.execute_remote_request() except exception.WazuhException as e: if self.debug: raise return self.print_json(data=e.message, error=e.code) except Exception as e: if self.debug: raise return self.print_json(data=str(e), error=1000)
def distribute_function(input_json, pretty=False, debug=False): """ Distributes an API call. :param input_json: API call to execute. :param pretty: JSON pretty print. :param debug: whether to raise an exception or return an error. :return: a JSON response """ try: node_info = cluster.get_node() request_type = rq.functions[input_json['function']]['type'] is_dapi_enabled = cluster.get_cluster_items( )['distributed_api']['enabled'] logger.debug("[Cluster] [D API ] Distributed API is {}.".format( "enabled" if is_dapi_enabled else "disabled")) if 'wait_for_complete' not in input_json['arguments']: input_json['arguments']['wait_for_complete'] = False # First case: execute the request local. # If the distributed api is not enabled # If the cluster is disabled or the request type is local_any # if the request was made in the master node and the request type is local_master # if the request came forwarded from the master node and its type is distributed_master if not is_dapi_enabled or not cluster.check_cluster_status() or request_type == 'local_any' or\ (request_type == 'local_master' and node_info['type'] == 'master') or\ (request_type == 'distributed_master' and input_json['from_cluster']): del input_json['arguments'][ 'wait_for_complete'] # local requests don't use this parameter return execute_local_request(input_json, pretty, debug) # Second case: forward the request # Only the master node will forward a request, and it will only be forwarded if its type is distributed_master elif request_type == 'distributed_master' and node_info[ 'type'] == 'master': return forward_request(input_json, node_info['node'], pretty, debug) # Last case: execute the request remotely. # A request will only be executed remotely if it was made in a worker node and its type isn't local_any else: return execute_remote_request(input_json, pretty) except WazuhException as e: return print_json(data=e.message, error=e.code, pretty=pretty) except Exception as e: if debug: raise return print_json(data=str(e), error=1000, pretty=pretty)
# Python 2/3 compability if sys.version_info[0] == 2: from Queue import Queue, Empty def base64_encoding(msg): return msg.encode('base64', 'strict') else: from queue import Queue, Empty import base64 unicode = str def base64_encoding(msg): return base64.b64encode(msg.encode()) if check_cluster_status(): try: from cryptography.fernet import Fernet, InvalidToken, InvalidSignature except ImportError as e: raise ImportError( "Could not import cryptography module. Install it using one of the following commands:\n\ - pip install cryptography\n\ - yum install python-cryptography python-setuptools\n\ - apt install python-cryptography") max_msg_size = 1000000 cmd_size = 12 logger = logging.getLogger(__name__) def msgbuild(counter, command, my_fernet, payload=None):