Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[master] Porting #49481 to master #54532

Merged
merged 4 commits into from
Oct 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions doc/ref/configuration/minion.rst
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,30 @@ Statically assigns grains to the minion.
cabinet: 13
cab_u: 14-15

.. conf_minion:: grains_blacklist

``grains_blacklist``
--------------------

Default: ``[]``

Each grains key will be compared against each of the expressions in this list.
Any keys which match will be filtered from the grains. Exact matches, glob
matches, and regular expressions are supported.

.. note::
Some states and execution modules depend on grains. Filtering may cause
them to be unavailable or run unreliably.

.. versionadded:: Neon

.. code-block:: yaml

grains_blacklist:
- cpu_flags
- zmq*
- ipv[46]

.. conf_minion:: grains_cache

``grains_cache``
Expand Down
4 changes: 4 additions & 0 deletions salt/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,9 @@ def _gather_buffer_space():
# Set a hard limit for the amount of memory modules can consume on a minion.
'modules_max_memory': int,

# Blacklist specific core grains to be filtered
'grains_blacklist': list,

# The number of minutes between the minion refreshing its cache of grains
'grains_refresh_every': int,

Expand Down Expand Up @@ -1222,6 +1225,7 @@ def _gather_buffer_space():
'cachedir': os.path.join(salt.syspaths.CACHE_DIR, 'minion'),
'append_minionid_config_dirs': [],
'cache_jobs': False,
'grains_blacklist': [],
'grains_cache': False,
'grains_cache_expiration': 300,
'grains_deep_merge': False,
Expand Down
18 changes: 18 additions & 0 deletions salt/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import salt.utils.odict
import salt.utils.platform
import salt.utils.versions
import salt.utils.stringutils
from salt.exceptions import LoaderError
from salt.template import check_render_pipe_str
from salt.utils.decorators import Depends
Expand Down Expand Up @@ -773,6 +774,7 @@ def grains(opts, force_refresh=False, proxy=None):
opts['grains'] = {}

grains_data = {}
blist = opts.get('grains_blacklist', [])
funcs = grain_funcs(opts, proxy=proxy)
if force_refresh: # if we refresh, lets reload grain modules
funcs.clear()
Expand All @@ -784,6 +786,14 @@ def grains(opts, force_refresh=False, proxy=None):
ret = funcs[key]()
if not isinstance(ret, dict):
continue
if blist:
for key in list(ret):
for block in blist:
if salt.utils.stringutils.expr_match(key, block):
del ret[key]
log.trace('Filtering %s grain', key)
if not ret:
continue
if grains_deep_merge:
salt.utils.dictupdate.update(grains_data, ret)
else:
Expand Down Expand Up @@ -819,6 +829,14 @@ def grains(opts, force_refresh=False, proxy=None):
continue
if not isinstance(ret, dict):
continue
if blist:
for key in list(ret):
for block in blist:
if salt.utils.stringutils.expr_match(key, block):
del ret[key]
log.trace('Filtering %s grain', key)
if not ret:
continue
if grains_deep_merge:
salt.utils.dictupdate.update(grains_data, ret)
else:
Expand Down
25 changes: 25 additions & 0 deletions tests/unit/test_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,31 @@ def test_whitelist(self):
self.assertNotIn('grains.get', self.loader)


class LazyLoaderGrainsBlacklistTest(TestCase):
'''
Test the loader of grains with a blacklist
'''
def setUp(self):
self.opts = salt.config.minion_config(None)

def tearDown(self):
del self.opts

def test_whitelist(self):
opts = copy.deepcopy(self.opts)
opts['grains_blacklist'] = [
'master',
'os*',
'ipv[46]'
]

grains = salt.loader.grains(opts)
self.assertNotIn('master', grains)
self.assertNotIn('os', set([g[:2] for g in list(grains)]))
self.assertNotIn('ipv4', grains)
self.assertNotIn('ipv6', grains)


class LazyLoaderSingleItem(TestCase):
'''
Test loading a single item via the _load() function
Expand Down