From 22d690945d49cce535d97ff3493ca10eac7f7c36 Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Wed, 8 Feb 2017 13:32:04 -0600 Subject: [PATCH 1/8] add optional extmod_whitelist dictionary --- salt/config/__init__.py | 5 +++++ salt/modules/saltutil.py | 14 +++++++------- salt/utils/extmods.py | 10 +++++++++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/salt/config/__init__.py b/salt/config/__init__.py index 55dc446e721f..6135467fc8d7 100644 --- a/salt/config/__init__.py +++ b/salt/config/__init__.py @@ -988,6 +988,9 @@ def _gather_buffer_space(): # Controls whether the scheduler is set up before a connection # to the master is attempted. 'scheduler_before_connect': bool, + + # Whitelist specific modules to be synced + 'extmod_whitelist': dict, } # default configurations @@ -1241,6 +1244,7 @@ def _gather_buffer_space(): 'beacons_before_connect': False, 'scheduler_before_connect': False, 'cache': 'localfs', + 'extmod_whitelist': {}, } DEFAULT_MASTER_OPTS = { @@ -1517,6 +1521,7 @@ def _gather_buffer_space(): 'thin_extra_mods': '', 'min_extra_mods': '', 'ssl': None, + 'extmod_whitelist': {}, } diff --git a/salt/modules/saltutil.py b/salt/modules/saltutil.py index 750eb9cb313b..6e2eebdeeb24 100644 --- a/salt/modules/saltutil.py +++ b/salt/modules/saltutil.py @@ -90,7 +90,7 @@ def _get_top_file_envs(): return envs -def _sync(form, saltenv=None): +def _sync(form, saltenv=None, extmod_whitelist=None): ''' Sync the given directory in the given environment ''' @@ -98,7 +98,7 @@ def _sync(form, saltenv=None): saltenv = _get_top_file_envs() if isinstance(saltenv, six.string_types): saltenv = saltenv.split(',') - ret, touched = salt.utils.extmods.sync(__opts__, form, saltenv=saltenv) + ret, touched = salt.utils.extmods.sync(__opts__, form, saltenv=saltenv, extmod_whitelist=extmod_whitelist) # Dest mod_dir is touched? trigger reload if requested if touched: mod_file = os.path.join(__opts__['cachedir'], 'module_refresh') @@ -180,7 +180,7 @@ def update(version=None): return ret -def sync_beacons(saltenv=None, refresh=True): +def sync_beacons(saltenv=None, refresh=True, extmod_whitelist=None): ''' .. versionadded:: 2015.5.1 @@ -203,13 +203,13 @@ def sync_beacons(saltenv=None, refresh=True): salt '*' saltutil.sync_beacons saltenv=dev salt '*' saltutil.sync_beacons saltenv=base,dev ''' - ret = _sync('beacons', saltenv) + ret = _sync('beacons', saltenv, extmod_whitelist) if refresh: refresh_beacons() return ret -def sync_sdb(saltenv=None): +def sync_sdb(saltenv=None, extmod_whitelist=None): ''' .. versionadded:: 2015.5.8,2015.8.3 @@ -231,11 +231,11 @@ def sync_sdb(saltenv=None): salt '*' saltutil.sync_sdb saltenv=dev salt '*' saltutil.sync_sdb saltenv=base,dev ''' - ret = _sync('sdb', saltenv) + ret = _sync('sdb', saltenv, extmod_whitelist) return ret -def sync_modules(saltenv=None, refresh=True): +def sync_modules(saltenv=None, refresh=True, extmod_whitelist=None): ''' .. versionadded:: 0.10.0 diff --git a/salt/utils/extmods.py b/salt/utils/extmods.py index 4b5cff3b6eb7..bd93d2d995c8 100644 --- a/salt/utils/extmods.py +++ b/salt/utils/extmods.py @@ -36,12 +36,18 @@ def _listdir_recursively(rootdir): return file_list -def sync(opts, form, saltenv=None): +def sync(opts, form, saltenv=None, extmod_whitelist=None): ''' Sync custom modules into the extension_modules directory ''' if saltenv is None: saltenv = ['base'] + if extmod_whitelist is None: + extmod_whitelist = opts['extmod_whitelist'] + elif isinstance(extmod_whitelist, six.string_types): + extmod_whitelist = {form: extmod_whitelist.split(',')} + elif not isinstance(extmod_whitelist, dict): + log.error('extmod_whitelist must be a string or dictionary: {0}'.format(extmod_whitelist)) if isinstance(saltenv, six.string_types): saltenv = saltenv.split(',') ret = [] @@ -86,6 +92,8 @@ def sync(opts, form, saltenv=None): for fn_ in cache: relpath = os.path.relpath(fn_, local_cache_dir) relname = os.path.splitext(relpath)[0].replace(os.sep, '.') + if extmod_whitelist and relname not in extmod_whitelist[form]: + continue remote.add(relpath) dest = os.path.join(mod_dir, relpath) log.info('Copying \'{0}\' to \'{1}\''.format(fn_, dest)) From 6c229396cc6a964b79f921af11811c66001fb0fc Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Wed, 8 Feb 2017 14:17:49 -0600 Subject: [PATCH 2/8] add extmod_whitelist to the saltutil modules --- salt/modules/saltutil.py | 113 ++++++++++++++++++++++++----------- salt/runners/saltutil.py | 123 ++++++++++++++++++++++++++------------- salt/utils/extmods.py | 2 +- 3 files changed, 162 insertions(+), 76 deletions(-) diff --git a/salt/modules/saltutil.py b/salt/modules/saltutil.py index 6e2eebdeeb24..e74d2888af06 100644 --- a/salt/modules/saltutil.py +++ b/salt/modules/saltutil.py @@ -195,6 +195,9 @@ def sync_beacons(saltenv=None, refresh=True, extmod_whitelist=None): will be performed even if no new beacons are synced. Set to ``False`` to prevent this refresh. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash @@ -223,6 +226,9 @@ def sync_sdb(saltenv=None, extmod_whitelist=None): This argument has no affect and is included for consistency with the other sync functions. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash @@ -267,6 +273,9 @@ def sync_modules(saltenv=None, refresh=True, extmod_whitelist=None): See :ref:`here ` for a more detailed explanation of why this is necessary. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash @@ -275,13 +284,13 @@ def sync_modules(saltenv=None, refresh=True, extmod_whitelist=None): salt '*' saltutil.sync_modules saltenv=dev salt '*' saltutil.sync_modules saltenv=base,dev ''' - ret = _sync('modules', saltenv) + ret = _sync('modules', saltenv, extmod_whitelist) if refresh: refresh_modules() return ret -def sync_states(saltenv=None, refresh=True): +def sync_states(saltenv=None, refresh=True, extmod_whitelist=None): ''' .. versionadded:: 0.10.0 @@ -296,6 +305,9 @@ def sync_states(saltenv=None, refresh=True): will be performed even if no new state modules are synced. Set to ``False`` to prevent this refresh. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Examples: .. code-block:: bash @@ -304,13 +316,13 @@ def sync_states(saltenv=None, refresh=True): salt '*' saltutil.sync_states saltenv=dev salt '*' saltutil.sync_states saltenv=base,dev ''' - ret = _sync('states', saltenv) + ret = _sync('states', saltenv, extmod_whitelist) if refresh: refresh_modules() return ret -def sync_grains(saltenv=None, refresh=True): +def sync_grains(saltenv=None, refresh=True, extmod_whitelist=None): ''' .. versionadded:: 0.10.0 @@ -326,6 +338,9 @@ def sync_grains(saltenv=None, refresh=True): new grains modules are synced. Set to ``False`` to prevent this refresh. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Examples: .. code-block:: bash @@ -334,14 +349,14 @@ def sync_grains(saltenv=None, refresh=True): salt '*' saltutil.sync_grains saltenv=dev salt '*' saltutil.sync_grains saltenv=base,dev ''' - ret = _sync('grains', saltenv) + ret = _sync('grains', saltenv, extmod_whitelist) if refresh: refresh_modules() refresh_pillar() return ret -def sync_renderers(saltenv=None, refresh=True): +def sync_renderers(saltenv=None, refresh=True, extmod_whitelist=None): ''' .. versionadded:: 0.10.0 @@ -357,6 +372,9 @@ def sync_renderers(saltenv=None, refresh=True): Set to ``False`` to prevent this refresh. Set to ``False`` to prevent this refresh. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Examples: .. code-block:: bash @@ -365,13 +383,13 @@ def sync_renderers(saltenv=None, refresh=True): salt '*' saltutil.sync_renderers saltenv=dev salt '*' saltutil.sync_renderers saltenv=base,dev ''' - ret = _sync('renderers', saltenv) + ret = _sync('renderers', saltenv, extmod_whitelist) if refresh: refresh_modules() return ret -def sync_returners(saltenv=None, refresh=True): +def sync_returners(saltenv=None, refresh=True, extmod_whitelist=None): ''' .. versionadded:: 0.10.0 @@ -386,6 +404,9 @@ def sync_returners(saltenv=None, refresh=True): This refresh will be performed even if no new returners are synced. Set to ``False`` to prevent this refresh. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Examples: .. code-block:: bash @@ -393,13 +414,13 @@ def sync_returners(saltenv=None, refresh=True): salt '*' saltutil.sync_returners salt '*' saltutil.sync_returners saltenv=dev ''' - ret = _sync('returners', saltenv) + ret = _sync('returners', saltenv, extmod_whitelist) if refresh: refresh_modules() return ret -def sync_proxymodules(saltenv=None, refresh=False): +def sync_proxymodules(saltenv=None, refresh=False, extmod_whitelist=None): ''' .. versionadded:: 2015.8.2 @@ -414,6 +435,9 @@ def sync_proxymodules(saltenv=None, refresh=False): This refresh will be performed even if no new proxy modules are synced. Set to ``False`` to prevent this refresh. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Examples: .. code-block:: bash @@ -422,13 +446,13 @@ def sync_proxymodules(saltenv=None, refresh=False): salt '*' saltutil.sync_proxymodules saltenv=dev salt '*' saltutil.sync_proxymodules saltenv=base,dev ''' - ret = _sync('proxy', saltenv) + ret = _sync('proxy', saltenv, extmod_whitelist) if refresh: refresh_modules() return ret -def sync_engines(saltenv=None, refresh=False): +def sync_engines(saltenv=None, refresh=False, extmod_whitelist=None): ''' .. versionadded:: 2016.3.0 @@ -443,6 +467,9 @@ def sync_engines(saltenv=None, refresh=False): This refresh will be performed even if no new engine modules are synced. Set to ``False`` to prevent this refresh. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Examples: .. code-block:: bash @@ -450,13 +477,13 @@ def sync_engines(saltenv=None, refresh=False): salt '*' saltutil.sync_engines salt '*' saltutil.sync_engines saltenv=base,dev ''' - ret = _sync('engines', saltenv) + ret = _sync('engines', saltenv, extmod_whitelist) if refresh: refresh_modules() return ret -def sync_output(saltenv=None, refresh=True): +def sync_output(saltenv=None, refresh=True, extmod_whitelist=None): ''' Sync outputters from ``salt://_output`` to the minion @@ -469,6 +496,9 @@ def sync_output(saltenv=None, refresh=True): This refresh will be performed even if no new outputters are synced. Set to ``False`` to prevent this refresh. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Examples: .. code-block:: bash @@ -477,7 +507,7 @@ def sync_output(saltenv=None, refresh=True): salt '*' saltutil.sync_output saltenv=dev salt '*' saltutil.sync_output saltenv=base,dev ''' - ret = _sync('output', saltenv) + ret = _sync('output', saltenv, extmod_whitelist) if refresh: refresh_modules() return ret @@ -485,7 +515,7 @@ def sync_output(saltenv=None, refresh=True): sync_outputters = salt.utils.alias_function(sync_output, 'sync_outputters') -def sync_utils(saltenv=None, refresh=True): +def sync_utils(saltenv=None, refresh=True, extmod_whitelist=None): ''' .. versionadded:: 2014.7.0 @@ -500,6 +530,9 @@ def sync_utils(saltenv=None, refresh=True): This refresh will be performed even if no new utility modules are synced. Set to ``False`` to prevent this refresh. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Examples: .. code-block:: bash @@ -508,7 +541,7 @@ def sync_utils(saltenv=None, refresh=True): salt '*' saltutil.sync_utils saltenv=dev salt '*' saltutil.sync_utils saltenv=base,dev ''' - ret = _sync('utils', saltenv) + ret = _sync('utils', saltenv, extmod_whitelist) if refresh: refresh_modules() return ret @@ -538,7 +571,7 @@ def list_extmods(): return ret -def sync_log_handlers(saltenv=None, refresh=True): +def sync_log_handlers(saltenv=None, refresh=True, extmod_whitelist=None): ''' .. versionadded:: 2015.8.0 @@ -553,6 +586,9 @@ def sync_log_handlers(saltenv=None, refresh=True): This refresh will be performed even if no new log handlers are synced. Set to ``False`` to prevent this refresh. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Examples: .. code-block:: bash @@ -561,13 +597,13 @@ def sync_log_handlers(saltenv=None, refresh=True): salt '*' saltutil.sync_log_handlers saltenv=dev salt '*' saltutil.sync_log_handlers saltenv=base,dev ''' - ret = _sync('log_handlers', saltenv) + ret = _sync('log_handlers', saltenv, extmod_whitelist) if refresh: refresh_modules() return ret -def sync_pillar(saltenv=None, refresh=True): +def sync_pillar(saltenv=None, refresh=True, extmod_whitelist=None): ''' .. versionadded:: 2015.8.11,2016.3.2 @@ -580,6 +616,9 @@ def sync_pillar(saltenv=None, refresh=True): Also refresh the execution modules available to the minion, and refresh pillar data. + extmod_whitelist : None + comma-seperated list of modules to sync + .. note:: This function will raise an error if executed on a traditional (i.e. not masterless) minion @@ -595,14 +634,14 @@ def sync_pillar(saltenv=None, refresh=True): raise CommandExecutionError( 'Pillar modules can only be synced to masterless minions' ) - ret = _sync('pillar', saltenv) + ret = _sync('pillar', saltenv, extmod_whitelist) if refresh: refresh_modules() refresh_pillar() return ret -def sync_all(saltenv=None, refresh=True): +def sync_all(saltenv=None, refresh=True, extmod_whitelist=None): ''' .. versionchanged:: 2015.8.11,2016.3.2 On masterless minions, pillar modules are now synced, and refreshed @@ -634,6 +673,9 @@ def sync_all(saltenv=None, refresh=True): See :ref:`here ` for a more detailed explanation of why this is necessary. + extmod_whitelist : None + dictionary of modules to sync based on type + CLI Examples: .. code-block:: bash @@ -641,23 +683,24 @@ def sync_all(saltenv=None, refresh=True): salt '*' saltutil.sync_all salt '*' saltutil.sync_all saltenv=dev salt '*' saltutil.sync_all saltenv=base,dev + salt '*' saltutil.sync_all extmod_whitelist={'modules': ['custom_module']} ''' log.debug('Syncing all') ret = {} - ret['beacons'] = sync_beacons(saltenv, False) - ret['modules'] = sync_modules(saltenv, False) - ret['states'] = sync_states(saltenv, False) - ret['sdb'] = sync_sdb(saltenv) - ret['grains'] = sync_grains(saltenv, False) - ret['renderers'] = sync_renderers(saltenv, False) - ret['returners'] = sync_returners(saltenv, False) - ret['output'] = sync_output(saltenv, False) - ret['utils'] = sync_utils(saltenv, False) - ret['log_handlers'] = sync_log_handlers(saltenv, False) - ret['proxymodules'] = sync_proxymodules(saltenv, False) - ret['engines'] = sync_engines(saltenv, False) + ret['beacons'] = sync_beacons(saltenv, False, extmod_whitelist) + ret['modules'] = sync_modules(saltenv, False, extmod_whitelist) + ret['states'] = sync_states(saltenv, False, extmod_whitelist) + ret['sdb'] = sync_sdb(saltenv, extmod_whitelist) + ret['grains'] = sync_grains(saltenv, False, extmod_whitelist) + ret['renderers'] = sync_renderers(saltenv, False, extmod_whitelist) + ret['returners'] = sync_returners(saltenv, False, extmod_whitelist) + ret['output'] = sync_output(saltenv, False, extmod_whitelist) + ret['utils'] = sync_utils(saltenv, False, extmod_whitelist) + ret['log_handlers'] = sync_log_handlers(saltenv, False, extmod_whitelist) + ret['proxymodules'] = sync_proxymodules(saltenv, False, extmod_whitelist) + ret['engines'] = sync_engines(saltenv, False, extmod_whitelist) if __opts__['file_client'] == 'local': - ret['pillar'] = sync_pillar(saltenv, False) + ret['pillar'] = sync_pillar(saltenv, False, extmod_whitelist) if refresh: refresh_modules() refresh_pillar() diff --git a/salt/runners/saltutil.py b/salt/runners/saltutil.py index 5e6a43b480ae..f04c9a6f0817 100644 --- a/salt/runners/saltutil.py +++ b/salt/runners/saltutil.py @@ -15,7 +15,7 @@ log = logging.getLogger(__name__) -def sync_all(saltenv='base'): +def sync_all(saltenv='base', extmod_whitelist=None): ''' Sync all custom types @@ -23,31 +23,35 @@ def sync_all(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + dictionary of modules to sync based on type + CLI Example: .. code-block:: bash salt-run saltutil.sync_all + salt-run saltutil.sync_all extmod_whitelist={'runners': ['custom_runner'], 'grains': []} ''' log.debug('Syncing all') ret = {} - ret['modules'] = sync_modules(saltenv=saltenv) - ret['states'] = sync_states(saltenv=saltenv) - ret['grains'] = sync_grains(saltenv=saltenv) - ret['renderers'] = sync_renderers(saltenv=saltenv) - ret['returners'] = sync_returners(saltenv=saltenv) - ret['output'] = sync_output(saltenv=saltenv) - ret['proxymodules'] = sync_proxymodules(saltenv=saltenv) - ret['runners'] = sync_runners(saltenv=saltenv) - ret['wheel'] = sync_wheel(saltenv=saltenv) - ret['engines'] = sync_engines(saltenv=saltenv) - ret['queues'] = sync_queues(saltenv=saltenv) - ret['pillar'] = sync_pillar(saltenv=saltenv) - ret['utils'] = sync_utils(saltenv=saltenv) + ret['modules'] = sync_modules(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['states'] = sync_states(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['grains'] = sync_grains(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['renderers'] = sync_renderers(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['returners'] = sync_returners(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['output'] = sync_output(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['proxymodules'] = sync_proxymodules(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['runners'] = sync_runners(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['wheel'] = sync_wheel(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['engines'] = sync_engines(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['queues'] = sync_queues(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['pillar'] = sync_pillar(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['utils'] = sync_utils(saltenv=saltenv, extmod_whitelist=extmod_whitelist) return ret -def sync_modules(saltenv='base'): +def sync_modules(saltenv='base', extmod_whitelist=None): ''' Sync execution modules from ``salt://_modules`` to the master @@ -55,16 +59,19 @@ def sync_modules(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_modules ''' - return salt.utils.extmods.sync(__opts__, 'modules', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'modules', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] -def sync_states(saltenv='base'): +def sync_states(saltenv='base', extmod_whitelist=None): ''' Sync state modules from ``salt://_states`` to the master @@ -72,16 +79,19 @@ def sync_states(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_states ''' - return salt.utils.extmods.sync(__opts__, 'states', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'states', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] -def sync_grains(saltenv='base'): +def sync_grains(saltenv='base', extmod_whitelist=None): ''' Sync grains modules from ``salt://_grains`` to the master @@ -89,16 +99,19 @@ def sync_grains(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_grains ''' - return salt.utils.extmods.sync(__opts__, 'grains', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'grains', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] -def sync_renderers(saltenv='base'): +def sync_renderers(saltenv='base', extmod_whitelist=None): ''' Sync renderer modules from from ``salt://_renderers`` to the master @@ -106,16 +119,19 @@ def sync_renderers(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_renderers ''' - return salt.utils.extmods.sync(__opts__, 'renderers', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'renderers', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] -def sync_returners(saltenv='base'): +def sync_returners(saltenv='base', extmod_whitelist=None): ''' Sync returner modules from ``salt://_returners`` to the master @@ -123,16 +139,19 @@ def sync_returners(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_returners ''' - return salt.utils.extmods.sync(__opts__, 'returners', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'returners', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] -def sync_output(saltenv='base'): +def sync_output(saltenv='base', extmod_whitelist=None): ''' Sync output modules from ``salt://_output`` to the master @@ -140,16 +159,19 @@ def sync_output(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_output ''' - return salt.utils.extmods.sync(__opts__, 'output', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'output', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] -def sync_proxymodules(saltenv='base'): +def sync_proxymodules(saltenv='base', extmod_whitelist=None): ''' Sync proxy modules from ``salt://_proxy`` to the master @@ -157,16 +179,19 @@ def sync_proxymodules(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_proxy ''' - return salt.utils.extmods.sync(__opts__, 'proxy', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'proxy', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] -def sync_runners(saltenv='base'): +def sync_runners(saltenv='base', extmod_whitelist=None): ''' Sync runners from ``salt://_runners`` to the master @@ -174,16 +199,19 @@ def sync_runners(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_runners ''' - return salt.utils.extmods.sync(__opts__, 'runners', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'runners', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] -def sync_wheel(saltenv='base'): +def sync_wheel(saltenv='base', extmod_whitelist=None): ''' Sync wheel modules from ``salt://_wheel`` to the master @@ -191,16 +219,19 @@ def sync_wheel(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_wheel ''' - return salt.utils.extmods.sync(__opts__, 'wheel', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'wheel', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] -def sync_engines(saltenv='base'): +def sync_engines(saltenv='base', extmod_whitelist=None): ''' Sync engines from ``salt://_engines`` to the master @@ -208,16 +239,19 @@ def sync_engines(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_engines ''' - return salt.utils.extmods.sync(__opts__, 'engines', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'engines', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] -def sync_queues(saltenv='base'): +def sync_queues(saltenv='base', extmod_whitelist=None): ''' Sync queue modules from ``salt://_queues`` to the master @@ -225,16 +259,19 @@ def sync_queues(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_queues ''' - return salt.utils.extmods.sync(__opts__, 'queues', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'queues', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] -def sync_pillar(saltenv='base'): +def sync_pillar(saltenv='base', extmod_whitelist=None): ''' Sync pillar modules from ``salt://_pillar`` to the master @@ -242,16 +279,19 @@ def sync_pillar(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_pillar ''' - return salt.utils.extmods.sync(__opts__, 'pillar', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'pillar', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] -def sync_utils(saltenv='base'): +def sync_utils(saltenv='base', extmod_whitelist=None): ''' .. versionadded:: 2016.11.0 @@ -261,10 +301,13 @@ def sync_utils(saltenv='base'): The fileserver environment from which to sync. To sync from more than one environment, pass a comma-separated list. + extmod_whitelist : None + comma-seperated list of modules to sync + CLI Example: .. code-block:: bash salt-run saltutil.sync_utils ''' - return salt.utils.extmods.sync(__opts__, 'utils', saltenv=saltenv)[0] + return salt.utils.extmods.sync(__opts__, 'utils', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] diff --git a/salt/utils/extmods.py b/salt/utils/extmods.py index bd93d2d995c8..45c4b8872f36 100644 --- a/salt/utils/extmods.py +++ b/salt/utils/extmods.py @@ -92,7 +92,7 @@ def sync(opts, form, saltenv=None, extmod_whitelist=None): for fn_ in cache: relpath = os.path.relpath(fn_, local_cache_dir) relname = os.path.splitext(relpath)[0].replace(os.sep, '.') - if extmod_whitelist and relname not in extmod_whitelist[form]: + if extmod_whitelist and form in extmod_whitelist and relname not in extmod_whitelist[form]: continue remote.add(relpath) dest = os.path.join(mod_dir, relpath) From 413ae1959269e8540636b808dfc2be839668c8d2 Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Wed, 8 Feb 2017 14:41:39 -0600 Subject: [PATCH 3/8] document extmod_whitelist for master and minion configs --- doc/ref/configuration/master.rst | 33 ++++++++++++++++++++++++++++++++ doc/ref/configuration/minion.rst | 32 +++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/doc/ref/configuration/master.rst b/doc/ref/configuration/master.rst index 5a87430547a3..6d8b17363e13 100644 --- a/doc/ref/configuration/master.rst +++ b/doc/ref/configuration/master.rst @@ -245,6 +245,39 @@ each of Salt's module types such as ``runners``, ``output``, ``wheel``, extension_modules: /root/salt_extmods +``extmod_whitelist`` +-------------------- + +.. versionadded:: Nitrogen + +By using this dictionary, the modules that are synced to the master's extmod cache using `saltutil.sync_*` can be +limited. If nothing is set to a specific type, then all modules are accepted. To block all modules of a specific type, +whitelist an empty list. + +.. code-block:: yaml + + extmod_whitelist: + modules: + - custom_module + engines: + - custom_engine + pillars: [] + +Valid options: + - modules + - states + - grains + - renderers + - returners + - output + - proxy + - runners + - wheel + - engines + - queues + - pillar + - utils + .. conf_master:: module_dirs ``module_dirs`` diff --git a/doc/ref/configuration/minion.rst b/doc/ref/configuration/minion.rst index d8d52b79551e..ef0b67e37142 100644 --- a/doc/ref/configuration/minion.rst +++ b/doc/ref/configuration/minion.rst @@ -1197,6 +1197,38 @@ below. providers: service: systemd +``extmod_whitelist`` +-------------------- + +.. versionadded:: Nitrogen + +By using this dictionary, the modules that are synced to the minion's extmod cache using `saltutil.sync_*`can be +limited. If nothing is set to a specific type, then all modules are accepted. To block all modules of a specific type, +whitelist an empty list. + +.. code-block:: yaml + + extmod_whitelist: + modules: + - custom_module + engines: + - custom_engine + pillars: [] + +Valid options: + - beacons + - sdb + - modules + - states + - grains + - renderers + - returners + - proxy + - engines + - output + - utils + - pillar + Top File Settings ================= From b0b2b5482b80af487dfc2f0fa45bdf3d1fce9c0f Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Wed, 8 Feb 2017 14:43:40 -0600 Subject: [PATCH 4/8] add sync_sdb to salt-run saltutil --- doc/ref/configuration/master.rst | 1 + salt/runners/saltutil.py | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/doc/ref/configuration/master.rst b/doc/ref/configuration/master.rst index 6d8b17363e13..53b4dea58051 100644 --- a/doc/ref/configuration/master.rst +++ b/doc/ref/configuration/master.rst @@ -277,6 +277,7 @@ Valid options: - queues - pillar - utils + - sdb .. conf_master:: module_dirs diff --git a/salt/runners/saltutil.py b/salt/runners/saltutil.py index f04c9a6f0817..3b36ca34db15 100644 --- a/salt/runners/saltutil.py +++ b/salt/runners/saltutil.py @@ -48,6 +48,7 @@ def sync_all(saltenv='base', extmod_whitelist=None): ret['queues'] = sync_queues(saltenv=saltenv, extmod_whitelist=extmod_whitelist) ret['pillar'] = sync_pillar(saltenv=saltenv, extmod_whitelist=extmod_whitelist) ret['utils'] = sync_utils(saltenv=saltenv, extmod_whitelist=extmod_whitelist) + ret['sdb'] = sync_sdb(saltenv=saltenv, extmod_whitelist=extmod_whitelist) return ret @@ -311,3 +312,25 @@ def sync_utils(saltenv='base', extmod_whitelist=None): salt-run saltutil.sync_utils ''' return salt.utils.extmods.sync(__opts__, 'utils', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] + + +def sync_sdb(saltenv='base', extmod_whitelist=None): + ''' + .. versionadded:: Nitrogen + + Sync utils modules from ``salt://_sdb`` to the master + + saltenv : base + The fileserver environment from which to sync. To sync from more than + one environment, pass a comma-separated list. + + extmod_whitelist : None + comma-seperated list of modules to sync + + CLI Example: + + .. code-block:: bash + + salt-run saltutil.sync_sdb + ''' + return salt.utils.extmods.sync(__opts__, 'sdb', saltenv=saltenv, extmod_whitelist=extmod_whitelist)[0] From e6f243e4cd6804d4eef1ace5058d5eb0e0910cce Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Wed, 8 Feb 2017 14:50:04 -0600 Subject: [PATCH 5/8] add note to clean_dynamic_modules --- doc/ref/configuration/minion.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/ref/configuration/minion.rst b/doc/ref/configuration/minion.rst index ef0b67e37142..ab7eac2f2e16 100644 --- a/doc/ref/configuration/minion.rst +++ b/doc/ref/configuration/minion.rst @@ -1448,6 +1448,10 @@ enabled and can be disabled by changing this value to ``False``. clean_dynamic_modules: True +.. note:: + + If ``extmod_whitelist`` is specified, modules which are not whitelisted will also be cleaned here. + .. conf_minion:: environment ``environment`` From fa72d5b5919b2a36ecda100736de4013210073e7 Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Wed, 8 Feb 2017 15:38:56 -0600 Subject: [PATCH 6/8] add clean_dynamic_modules to master default opts --- salt/config/__init__.py | 1 + salt/utils/extmods.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/salt/config/__init__.py b/salt/config/__init__.py index 6135467fc8d7..33992a2b643d 100644 --- a/salt/config/__init__.py +++ b/salt/config/__init__.py @@ -1522,6 +1522,7 @@ def _gather_buffer_space(): 'min_extra_mods': '', 'ssl': None, 'extmod_whitelist': {}, + 'clean_dynamic_modules': True, } diff --git a/salt/utils/extmods.py b/salt/utils/extmods.py index 45c4b8872f36..23c0d9fd4ba4 100644 --- a/salt/utils/extmods.py +++ b/salt/utils/extmods.py @@ -114,7 +114,7 @@ def sync(opts, form, saltenv=None, extmod_whitelist=None): ret.append('{0}.{1}'.format(form, relname)) touched = bool(ret) - if opts.get('clean_dynamic_modules', True): + if opts['clean_dynamic_modules'] is True: current = set(_listdir_recursively(mod_dir)) for fn_ in current - remote: full = os.path.join(mod_dir, fn_) From 57ab8dd27b65cd5303556df27a09c94ce1aef04d Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Wed, 8 Feb 2017 15:39:26 -0600 Subject: [PATCH 7/8] add integration test --- tests/integration/modules/saltutil.py | 55 +++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tests/integration/modules/saltutil.py b/tests/integration/modules/saltutil.py index 508f61f88ff6..66c866733210 100644 --- a/tests/integration/modules/saltutil.py +++ b/tests/integration/modules/saltutil.py @@ -61,6 +61,61 @@ def test_wheel_with_kwarg(self): self.assertIn('priv', ret['return']) +class SaltUtilSyncModuleTest(integration.ModuleCase): + ''' + Testcase for the saltutil sync execution module + ''' + + def setUp(self): + whitelist = {'modules': [],} + self.run_function('saltutil.sync_all', extmod_whitelist=whitelist) + + def tearDown(self): + self.run_function('saltutil.sync_all') + + def test_sync_all(self): + ''' + Test syncing all ModuleCase + ''' + expected_return = {'engines': [], + 'grains': [], + 'beacons': [], + 'utils': [], + 'returners': [], + 'modules': ['modules.override_test', + 'modules.runtests_decorators', + 'modules.runtests_helpers', + 'modules.salttest'], + 'renderers': [], + 'log_handlers': [], + 'states': [], + 'sdb': [], + 'proxymodules': [], + 'output': []} + ret = self.run_function('saltutil.sync_all') + self.assertEqual(ret, expected_return) + + def test_sync_all_whitelist(self): + ''' + Test syncing all ModuleCase + ''' + expected_return = {'engines': [], + 'grains': [], + 'beacons': [], + 'utils': [], + 'returners': [], + 'modules': ['modules.salttest'], + 'renderers': [], + 'log_handlers': [], + 'states': [], + 'sdb': [], + 'proxymodules': [], + 'output': []} + ret = self.run_function('saltutil.sync_all', extmod_whitelist={'modules': ['salttest']}) + self.assertEqual(ret, expected_return) + + if __name__ == '__main__': from integration import run_tests run_tests(SaltUtilModuleTest) + run_tests(SaltUtilSyncModuleTest) From e38c5d296bad26f8564ff8d5585c6712a9c53abd Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Wed, 8 Feb 2017 18:07:13 -0600 Subject: [PATCH 8/8] fix pylint --- tests/integration/modules/saltutil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/modules/saltutil.py b/tests/integration/modules/saltutil.py index 66c866733210..cb072fa8c59f 100644 --- a/tests/integration/modules/saltutil.py +++ b/tests/integration/modules/saltutil.py @@ -67,7 +67,7 @@ class SaltUtilSyncModuleTest(integration.ModuleCase): ''' def setUp(self): - whitelist = {'modules': [],} + whitelist = {'modules': [], } self.run_function('saltutil.sync_all', extmod_whitelist=whitelist) def tearDown(self):