Skip to content

Commit

Permalink
Merge pull request #49411 from terminalmage/issue49269-2018.3
Browse files Browse the repository at this point in the history
Allow our custom yaml dumper to NamespacedDictWrapper objects (2018.3 branch)
  • Loading branch information
Nicole Thomas committed Aug 30, 2018
2 parents 8022a3b + a4cb35b commit a962efc
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 7 deletions.
4 changes: 2 additions & 2 deletions salt/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -1380,11 +1380,11 @@ def __prep_mod_opts(self, opts):
'''
if '__grains__' not in self.pack:
self.context_dict['grains'] = opts.get('grains', {})
self.pack['__grains__'] = salt.utils.context.NamespacedDictWrapper(self.context_dict, 'grains', override_name='grains')
self.pack['__grains__'] = salt.utils.context.NamespacedDictWrapper(self.context_dict, 'grains')

if '__pillar__' not in self.pack:
self.context_dict['pillar'] = opts.get('pillar', {})
self.pack['__pillar__'] = salt.utils.context.NamespacedDictWrapper(self.context_dict, 'pillar', override_name='pillar')
self.pack['__pillar__'] = salt.utils.context.NamespacedDictWrapper(self.context_dict, 'pillar')

mod_opts = {}
for key, val in list(opts.items()):
Expand Down
12 changes: 8 additions & 4 deletions salt/utils/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,14 @@ def __init__(self, d, pre_keys, override_name=None): # pylint: disable=W0231
self.pre_keys = (pre_keys,)
else:
self.pre_keys = pre_keys
if override_name:
self.__class__.__module__ = 'salt'
# __name__ can't be assigned a unicode
self.__class__.__name__ = str(override_name) # future lint: disable=blacklisted-function
if override_name is not None:
import salt.utils.versions
salt.utils.versions.warn_until(
'Neon',
'Overriding the class name is no longer supported. Please '
'remove the override_name argument before it is removed in '
'Salt Sodium.'
)
super(NamespacedDictWrapper, self).__init__(self._dict())

def _dict(self):
Expand Down
10 changes: 9 additions & 1 deletion salt/utils/yamldumper.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import yaml # pylint: disable=blacklisted-import
import collections

import salt.utils.context
from salt.utils.odict import OrderedDict

try:
Expand Down Expand Up @@ -77,6 +77,14 @@ def represent_ordereddict(dumper, data):
collections.defaultdict,
yaml.representer.SafeRepresenter.represent_dict
)
OrderedDumper.add_representer(
salt.utils.context.NamespacedDictWrapper,
yaml.representer.SafeRepresenter.represent_dict
)
SafeOrderedDumper.add_representer(
salt.utils.context.NamespacedDictWrapper,
yaml.representer.SafeRepresenter.represent_dict
)

OrderedDumper.add_representer(
'tag:yaml.org,2002:timestamp',
Expand Down
15 changes: 15 additions & 0 deletions tests/integration/output/test_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

# Import Salt libs
import salt.config
import salt.utils.yaml
from salt.output import display_output
from salt.ext import six

Expand Down Expand Up @@ -82,6 +83,20 @@ def test_output_yaml(self):
ret = self.run_call('test.ping --out=yaml')
self.assertEqual(ret, expected)

def test_output_yaml_namespaced_dict_wrapper(self):
'''
Tests the ability to dump a NamespacedDictWrapper instance, as used in
magic dunders like __grains__ and __pillar__
See https://github.com/saltstack/salt/issues/49269
'''
dumped_yaml = '\n'.join(self.run_call('grains.items --out=yaml'))
loaded_yaml = salt.utils.yaml.safe_load(dumped_yaml)
# We just want to check that the dumped YAML loades as a dict with a
# single top-level key, we don't care about the real contents.
assert isinstance(loaded_yaml, dict)
assert list(loaded_yaml) == ['local']

def test_output_unicodebad(self):
'''
Tests outputter reliability with utf8
Expand Down

0 comments on commit a962efc

Please sign in to comment.