mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Merge pull request #10600 from borgstrom/pyobjects_saltobject
Adding a object interface to __salt__ & __pillar__ (pyobjects)
This commit is contained in:
commit
7a3bf8aa85
@ -105,12 +105,49 @@ a state.
|
||||
|
||||
Service.running(Extend('apache'),
|
||||
watch=[{'file': '/etc/httpd/extra/httpd-vhosts.conf'}])
|
||||
|
||||
Pillar data
|
||||
^^^^^^^^^^^
|
||||
Pyobjects provides a shortcut function for calling ``salt['pillar.get']`` that
|
||||
helps maintain the readability of your state files. It can be accessed using
|
||||
the ``Pillar`` object.
|
||||
|
||||
The following lines are functionally equivalent:
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
#!pyobjects
|
||||
|
||||
value = Pillar('foo:bar:baz', 'qux')
|
||||
value = salt['pillar.get']('foo:bar:baz', 'qux')
|
||||
|
||||
SaltObject
|
||||
^^^^^^^^^^
|
||||
In the spirit of the object interface for creating state data pyobjects also
|
||||
provides a simple object interface to the ``__salt__`` object.
|
||||
|
||||
An object named ``Salt`` exists in scope for your sls files and will dispatch
|
||||
its attributes to the ``__salt__`` dictionary.
|
||||
|
||||
The following lines are functionally equivalent:
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
#!pyobjects
|
||||
|
||||
ret = Salt.cmd.run(bar)
|
||||
ret = salt['cmd.run'](bar)
|
||||
|
||||
|
||||
TODO
|
||||
^^^^
|
||||
* Interface for working with reactor files
|
||||
'''
|
||||
|
||||
import logging
|
||||
|
||||
from salt.loader import states
|
||||
from salt.utils.pyobjects import StateRegistry
|
||||
from salt.utils.pyobjects import StateRegistry, SaltObject
|
||||
from salt.utils.pyobjects import StateFactory # pylint: disable=W0611
|
||||
# DO NOT REMOVE THE DISABLE ABOVE, it's used in an exec call below
|
||||
|
||||
@ -153,6 +190,12 @@ def render(template, saltenv='base', sls='',
|
||||
pillar = __pillar__
|
||||
grains = __grains__
|
||||
salt = __salt__
|
||||
|
||||
# create our SaltObject
|
||||
Salt = SaltObject(__salt__)
|
||||
|
||||
# add a Pillar shortcut
|
||||
Pillar = __salt__['pillar.get']
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
Pythonic object interface to creating state data, see the pyobjects renderer
|
||||
for more documentation.
|
||||
'''
|
||||
from collections import namedtuple
|
||||
|
||||
from salt.utils.odict import OrderedDict
|
||||
|
||||
REQUISITES = ('require', 'watch', 'use', 'require_in', 'watch_in', 'use_in')
|
||||
@ -228,3 +230,36 @@ class State(object):
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self.registry.pop_requisite()
|
||||
|
||||
|
||||
class SaltObject(object):
|
||||
'''
|
||||
Object based interface to the functions in __salt__
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
Salt = SaltObject(__salt__)
|
||||
Salt.cmd.run(bar)
|
||||
'''
|
||||
def __init__(self, salt):
|
||||
_mods = {}
|
||||
for full_func in salt:
|
||||
mod, func = full_func.split('.')
|
||||
|
||||
if mod not in _mods:
|
||||
_mods[mod] = {}
|
||||
_mods[mod][func] = salt[full_func]
|
||||
|
||||
# now transform using namedtuples
|
||||
self.mods = {}
|
||||
for mod in _mods:
|
||||
mod_object = namedtuple('%sModule' % mod.capitalize(),
|
||||
_mods[mod].keys())
|
||||
|
||||
self.mods[mod] = mod_object(**_mods[mod])
|
||||
|
||||
def __getattr__(self, mod):
|
||||
if mod not in self.mods:
|
||||
raise AttributeError
|
||||
|
||||
return self.mods[mod]
|
||||
|
@ -13,7 +13,7 @@ from salt.minion import SMinion
|
||||
from salt.renderers.pyobjects import render as pyobjects_render
|
||||
from salt.utils.odict import OrderedDict
|
||||
from salt.utils.pyobjects import (StateFactory, State, StateRegistry,
|
||||
InvalidFunction)
|
||||
InvalidFunction, SaltObject)
|
||||
|
||||
test_registry = StateRegistry()
|
||||
File = StateFactory('file', registry=test_registry)
|
||||
@ -31,22 +31,22 @@ pydmesg_salt_expected = OrderedDict([('/usr/local/bin/pydmesg', pydmesg_expected
|
||||
pydmesg_kwargs = dict(user='root', group='root', mode='0755',
|
||||
source='salt://debian/files/pydmesg.py')
|
||||
|
||||
basic_template = """#!pyobjects
|
||||
basic_template = '''#!pyobjects
|
||||
File.directory('/tmp', mode='1777', owner='root', group='root')
|
||||
"""
|
||||
'''
|
||||
|
||||
invalid_template = """#!pyobjects
|
||||
invalid_template = '''#!pyobjects
|
||||
File.fail('/tmp')
|
||||
"""
|
||||
'''
|
||||
|
||||
include_template = """#!pyobjects
|
||||
include_template = '''#!pyobjects
|
||||
Include('http')
|
||||
"""
|
||||
'''
|
||||
|
||||
extend_template = """#!pyobjects
|
||||
extend_template = '''#!pyobjects
|
||||
Include('http')
|
||||
Service.running(Extend('apache'), watch=[{'file': '/etc/file'}])
|
||||
"""
|
||||
'''
|
||||
|
||||
|
||||
class StateTests(TestCase):
|
||||
@ -163,3 +163,22 @@ class RendererTests(TestCase):
|
||||
}),
|
||||
])),
|
||||
]))
|
||||
|
||||
|
||||
class SaltObjectTests(TestCase):
|
||||
def test_salt_object(self):
|
||||
def attr_fail():
|
||||
Salt.fail.blah()
|
||||
|
||||
def times2(x):
|
||||
return x*2
|
||||
|
||||
__salt__ = {
|
||||
'math.times2': times2
|
||||
}
|
||||
|
||||
Salt = SaltObject(__salt__)
|
||||
|
||||
self.assertRaises(AttributeError, attr_fail)
|
||||
self.assertEqual(Salt.math.times2, times2)
|
||||
self.assertEqual(Salt.math.times2(2), 4)
|
||||
|
Loading…
Reference in New Issue
Block a user