1""" 2This module contains routines used for the salt mine 3""" 4 5 6import logging 7 8import salt.utils.data 9 10log = logging.getLogger(__name__) 11 12MINE_ITEM_ACL_ID = "__saltmine_acl__" 13MINE_ITEM_ACL_VERSION = 1 14MINE_ITEM_ACL_DATA = "__data__" 15 16 17def minion_side_acl_denied(minion_acl_cache, mine_minion, mine_function, req_minion): 18 """ 19 Helper function to determine if a ``req_minion`` is not allowed to retrieve 20 ``mine_function``-data from the mine of ``mine_minion``. 21 22 :param dict minion_acl_cache: Contains minion_id as first level key, and mine 23 function as 2nd level key. Value of 2nd level is a list of minions that 24 are allowed to retrieve the function from the mine of the minion. 25 :param str mine_minion: The minion that the mine value originated from. 26 :param str mine_function: The mine function that is requested. 27 :param str req_minion: The minion that is requesting the mine data. 28 29 :rtype: bool 30 :return: 31 False if no ACL has been defined for ``mine_minion``, ``mine_function``. 32 False if an ACL has been defined and it grants access. 33 True if an ACL has been defined and does not grant access. 34 """ 35 minion_acl_entry = minion_acl_cache.get(mine_minion, {}).get(mine_function, []) 36 ret = minion_acl_entry and req_minion not in minion_acl_entry 37 if ret: 38 log.debug( 39 "Salt mine request from %s for function %s on minion %s denied.", 40 req_minion, 41 mine_function, 42 mine_minion, 43 ) 44 return ret 45 46 47def wrap_acl_structure(function_data, allow_tgt=None, allow_tgt_type=None): 48 """ 49 Helper function to convert an non-ACL mine entry into the new entry which 50 includes ACL data. 51 52 :param dict function_data: The function data to wrap. 53 :param str allow_tgt: The targeting string that designates which minions can 54 request this mine entry. 55 :param str allow_tgt_type: The type of targeting string. 56 .. seealso:: :ref:`targeting` 57 58 :rtype: dict 59 :return: Mine entry structured to include ACL data. 60 """ 61 res = { 62 MINE_ITEM_ACL_DATA: function_data, 63 MINE_ITEM_ACL_ID: MINE_ITEM_ACL_VERSION, 64 } 65 # Add minion-side ACL 66 if allow_tgt: 67 res.update( 68 salt.utils.data.filter_falsey( 69 {"allow_tgt": allow_tgt, "allow_tgt_type": allow_tgt_type} 70 ) 71 ) 72 return res 73 74 75def parse_function_definition(function_definition): 76 """ 77 Helper function to parse the mine_function definition as provided in config, 78 or pillar. 79 80 :param function_definition: The function definition to parse. 81 :type function_definition: list or dict 82 83 :rtype: tuple 84 :return: Tuple with function_name, function_args, function_kwargs, minion_acl (dict) 85 """ 86 function_name = None 87 function_args = [] 88 function_kwargs = {} 89 minion_acl = {} 90 if isinstance(function_definition, dict): 91 # dictionary format for specifying mine function 92 function_name = function_definition.pop("mine_function", None) 93 function_kwargs = function_definition 94 elif isinstance(function_definition, list): 95 for item in function_definition: 96 if isinstance(item, dict): 97 # if len(item) > 1: # Multiple kwargs in a single list item 98 function_kwargs.update(item) 99 else: 100 function_args.append(item) 101 function_name = function_kwargs.pop("mine_function", None) 102 103 minion_acl = salt.utils.data.filter_falsey( 104 { 105 "allow_tgt": function_kwargs.pop("allow_tgt", None), 106 "allow_tgt_type": function_kwargs.pop("allow_tgt_type", None), 107 } 108 ) 109 110 return (function_name, function_args, function_kwargs, minion_acl) 111