From 05ab624fcd8106c69785248822c2f731cefa4720 Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Fri, 27 Apr 2018 15:22:38 -0500 Subject: [PATCH] Allow for passing in previously compiled grains to custom grain modules Closes #47338 --- doc/topics/grains/index.rst | 5 +++++ doc/topics/releases/fluorine.rst | 10 +++++++++ salt/loader.py | 10 +++++++-- .../file/base/_grains/test_custom_grains.py | 4 ++++ tests/integration/grains/test_custom.py | 22 +++++++++++++++++++ 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 tests/integration/files/file/base/_grains/test_custom_grains.py create mode 100644 tests/integration/grains/test_custom.py diff --git a/doc/topics/grains/index.rst b/doc/topics/grains/index.rst index 2b19678152..d1fbee3b70 100644 --- a/doc/topics/grains/index.rst +++ b/doc/topics/grains/index.rst @@ -269,6 +269,11 @@ grain will override that core grain. Similarly, grains from ``/etc/salt/minion`` override both core grains and custom grain modules, and grains in ``_grains`` will override *any* grains of the same name. +For custom grains, if the function takes an argument ``grains``, then the +previously rendered grains will be passed in. Because the rest of the grains +could be rendered in any order, the only grains that can be relied upon to be +passed in are ``core`` grains. This was added in the Fluorine Release. + Examples of Grains ================== diff --git a/doc/topics/releases/fluorine.rst b/doc/topics/releases/fluorine.rst index 9b73d0cfc6..1926747ba2 100644 --- a/doc/topics/releases/fluorine.rst +++ b/doc/topics/releases/fluorine.rst @@ -5,6 +5,16 @@ Salt Release Notes - Codename Fluorine ====================================== +Grains Dictionary Passed into Custom Grains +------------------------------------------- + +Starting in this release, if a custom grains function accepts a variable named +``grains``, the Grains dictionary of the already compiled grains will be passed +in. Because of the non deterministic order that grains are rendered in, the +only grains that can be relied upon to be passed in are ``core.py`` grains, +since those are compiled first. + + "Virtual Package" Support Dropped for APT ----------------------------------------- diff --git a/salt/loader.py b/salt/loader.py index 56b4b038ea..4b07cb3afc 100644 --- a/salt/loader.py +++ b/salt/loader.py @@ -751,8 +751,14 @@ def grains(opts, force_refresh=False, proxy=None): # proxymodule for retrieving information from the connected # device. log.trace('Loading %s grain', key) - if funcs[key].__code__.co_argcount == 1: - ret = funcs[key](proxy) + parameters = list(funcs[key].__code__.co_varnames) + if funcs[key].__code__.co_argcount > 0: + kwargs = {} + if 'proxy' in parameters: + kwargs['proxy'] = proxy + if 'grains' in parameters: + kwargs['grains'] = grains_data + ret = funcs[key](**kwargs) else: ret = funcs[key]() except Exception: diff --git a/tests/integration/files/file/base/_grains/test_custom_grains.py b/tests/integration/files/file/base/_grains/test_custom_grains.py new file mode 100644 index 0000000000..639803bafc --- /dev/null +++ b/tests/integration/files/file/base/_grains/test_custom_grains.py @@ -0,0 +1,4 @@ +def test(grains): + if 'os' in grains: + return {'custom_grain_test': 'itworked'} + return {'custom_grain_test': 'itdidntwork'} diff --git a/tests/integration/grains/test_custom.py b/tests/integration/grains/test_custom.py new file mode 100644 index 0000000000..f9c534d812 --- /dev/null +++ b/tests/integration/grains/test_custom.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +''' +Test the core grains +''' + +# Import python libs +from __future__ import absolute_import, unicode_literals + +# Import Salt Testing libs +from tests.support.case import ModuleCase + + +class TestGrainsCore(ModuleCase): + ''' + Test the core grains grains + ''' + + def test_grains_passed_to_custom_grain(self): + ''' + test if current grains are passed to grains module functions that have a grains argument + ''' + self.assertEqual(self.run_function('grains.get', ['custom_grain_test']), 'itworked')