Exemple #1
0
    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)
Exemple #2
0
def render(template, saltenv='base', sls='', salt_data=True, **kwargs):
    if 'pyobjects_states' not in __context__:
        load_states()

    # these hold the scope that our sls file will be executed with
    _globals = {}

    # create our StateFactory objects
    mod_globals = {'StateFactory': StateFactory}
    for mod in __context__['pyobjects_states']:
        mod_locals = {}
        mod_camel = ''.join([part.capitalize() for part in mod.split('_')])
        valid_funcs = "','".join(__context__['pyobjects_states'][mod])
        mod_cmd = "{0} = StateFactory('{1!s}', valid_funcs=['{2}'])".format(
            mod_camel, mod, valid_funcs)
        exec_(mod_cmd, mod_globals, mod_locals)

        _globals[mod_camel] = mod_locals[mod_camel]

    # add our include and extend functions
    _globals['include'] = Registry.include
    _globals['extend'] = Registry.make_extend

    # add our map class
    Map.__salt__ = __salt__
    _globals['Map'] = Map

    # add some convenience methods to the global scope as well as the "dunder"
    # format of all of the salt objects
    try:
        _globals.update({
            # salt, pillar & grains all provide shortcuts or object interfaces
            'salt': SaltObject(__salt__),
            'pillar': __salt__['pillar.get'],
            'grains': __salt__['grains.get'],
            'mine': __salt__['mine.get'],
            'config': __salt__['config.get'],

            # the "dunder" formats are still available for direct use
            '__salt__': __salt__,
            '__pillar__': __pillar__,
            '__grains__': __grains__
        })
    except NameError:
        pass

    # if salt_data is not True then we just return the global scope we've
    # built instead of returning salt data from the registry
    if not salt_data:
        return _globals

    # this will be used to fetch any import files
    client = get_file_client(__opts__)

    # process our sls imports
    #
    # we allow pyobjects users to use a special form of the import statement
    # so that they may bring in objects from other files. while we do this we
    # disable the registry since all we're looking for here is python objects,
    # not salt state data
    template_data = []
    Registry.enabled = False
    for line in template.readlines():
        line = line.rstrip('\r\n')
        matched = False
        for RE in (IMPORT_RE, FROM_RE):
            matches = RE.match(line)
            if not matches:
                continue

            import_file = matches.group(1).strip()
            try:
                imports = matches.group(2).split(',')
            except IndexError:
                # if we don't have a third group in the matches object it means
                # that we're importing everything
                imports = None

            state_file = client.cache_file(import_file, saltenv)
            if not state_file:
                raise ImportError(
                    "Could not find the file {0!r}".format(import_file))

            with salt.utils.fopen(state_file) as f:
                state_contents = f.read()

            state_locals = {}
            exec_(state_contents, _globals, state_locals)

            if imports is None:
                imports = list(state_locals)

            for name in imports:
                name = alias = name.strip()

                matches = FROM_AS_RE.match(name)
                if matches is not None:
                    name = matches.group(1).strip()
                    alias = matches.group(2).strip()

                if name not in state_locals:
                    raise ImportError("{0!r} was not found in {1!r}".format(
                        name, import_file))
                _globals[alias] = state_locals[name]

            matched = True
            break

        if not matched:
            template_data.append(line)

    final_template = "\n".join(template_data)

    # re-enable the registry
    Registry.enabled = True

    # now exec our template using our created scopes
    exec_(final_template, _globals)

    return Registry.salt_data()
Exemple #3
0
def render(template,
           saltenv='base',
           sls='',
           tmplpath=None,
           rendered_sls=None,
           _states=None,
           **kwargs):

    _globals = {}
    _locals = {}

    _registry = StateRegistry()
    if _states is None:
        try:
            _states = __states__
        except NameError:
            from salt.loader import states
            __opts__['grains'] = __grains__
            __opts__['pillar'] = __pillar__
            _states = states(__opts__, __salt__)

    # build our list of states and functions
    _st_funcs = {}
    for func in _states:
        (mod, func) = func.split(".")
        if mod not in _st_funcs:
            _st_funcs[mod] = []
        _st_funcs[mod].append(func)

    # create our StateFactory objects
    _st_globals = {'StateFactory': StateFactory, '_registry': _registry}
    for mod in _st_funcs:
        _st_locals = {}
        _st_funcs[mod].sort()
        mod_camel = ''.join([part.capitalize() for part in mod.split('_')])
        mod_cmd = "%s = StateFactory('%s', registry=_registry, valid_funcs=['%s'])" % (
            mod_camel, mod, "','".join(_st_funcs[mod]))
        if sys.version > 3:
            exec(mod_cmd, _st_globals, _st_locals)
        else:
            exec mod_cmd in _st_globals, _st_locals
        _globals[mod_camel] = _st_locals[mod_camel]

    # add our Include and Extend functions
    _globals['include'] = _registry.include
    _globals['extend'] = _registry.make_extend

    # for convenience
    try:
        _globals.update({
            # salt, pillar & grains all provide shortcuts or object interfaces
            'salt': SaltObject(__salt__),
            'pillar': __salt__['pillar.get'],
            'grains': __salt__['grains.get'],
            'mine': __salt__['mine.get'],

            # the "dunder" formats are still available for direct use
            '__salt__': __salt__,
            '__pillar__': __pillar__,
            '__grains__': __grains__
        })
    except NameError:
        pass

    if sys.version > 3:
        exec(template.read(), _globals, _locals)
    else:
        exec template.read() in _globals, _locals

    return _registry.salt_data()
Exemple #4
0
def render(template, saltenv='base', sls='', **kwargs):
    if 'pyobjects_states' not in __context__:
        load_states()

    # these hold the scope that our sls file will be executed with
    _globals = {}
    _locals = {}

    # this will be used to fetch any import files
    client = get_file_client(__opts__)

    # create our StateFactory objects
    mod_globals = {'StateFactory': StateFactory}
    for mod in __context__['pyobjects_states']:
        mod_locals = {}
        mod_camel = ''.join([part.capitalize() for part in mod.split('_')])
        valid_funcs = "','".join(__context__['pyobjects_states'][mod].keys())
        mod_cmd = "{0} = StateFactory('{1!s}', valid_funcs=['{2}'])".format(
            mod_camel, mod, valid_funcs)
        if sys.version_info[0] > 2:
            # in py3+ exec is a function
            exec(mod_cmd, mod_globals, mod_locals)
        else:
            # prior to that it is a statement
            exec mod_cmd in mod_globals, mod_locals

        _globals[mod_camel] = mod_locals[mod_camel]

    # add our include and extend functions
    _globals['include'] = Registry.include
    _globals['extend'] = Registry.make_extend

    # add our map class
    Map.__salt__ = __salt__
    _globals['Map'] = Map

    # add some convenience methods to the global scope as well as the "dunder"
    # format of all of the salt objects
    try:
        _globals.update({
            # salt, pillar & grains all provide shortcuts or object interfaces
            'salt': SaltObject(__salt__),
            'pillar': __salt__['pillar.get'],
            'grains': __salt__['grains.get'],
            'mine': __salt__['mine.get'],

            # the "dunder" formats are still available for direct use
            '__salt__': __salt__,
            '__pillar__': __pillar__,
            '__grains__': __grains__
        })
    except NameError:
        pass

    # process our sls imports
    #
    # we allow pyobjects users to use a special form of the import statement
    # so that they may bring in objects from other files. while we do this we
    # disable the registry since all we're looking for here is python objects,
    # not salt state data
    #
    # once we have our template we scan through it and look for any "from X
    # import Y" statements and if X ends in .sls then we process it by passing
    # the file in X through the pyobjects renderer and putting the requested
    # variables into our template
    template_data = []
    Registry.enabled = False
    for line in template.readlines():
        line = line.rstrip('\r\n')
        matched = False
        for RE in (IMPORT_RE, FROM_RE):
            matches = re.match(RE, line)
            if not matches:
                continue

            import_file = matches.group(1).strip()
            try:
                imports = matches.group(2).split(',')
            except IndexError:
                # if we don't have a third group in the matches object it means
                # that we're importing everything
                imports = None

            state_file = client.cache_file(import_file, saltenv)
            if not state_file:
                raise ImportError(
                    "Could not find the file {0!r}".format(import_file))

            with open(state_file) as f:
                state_contents = f.read()

            state_locals = {}
            if sys.version_info[0] > 2:
                # in py3+ exec is a function
                exec(state_contents, _globals, state_locals)
            else:
                # prior to that it is a statement
                exec state_contents in _globals, state_locals

            if imports is None:
                imports = state_locals.keys()

            for name in imports:
                name = name.strip()
                if name not in state_locals:
                    raise ImportError("{0!r} was not found in {1!r}".format(
                        name, import_file))
                _globals[name] = state_locals[name]

            matched = True
            break

        if not matched:
            template_data.append(line)

    final_template = "\n".join(template_data)

    # re-enable the registry
    Registry.enabled = True

    # now exec our template using our created scopes
    if sys.version_info[0] > 2:
        # in py3+ exec is a function
        exec(final_template, _globals, _locals)
    else:
        # prior to that it is a statement
        exec final_template in _globals, _locals

    return Registry.salt_data()
Exemple #5
0
def render(template, saltenv="base", sls="", salt_data=True, **kwargs):
    if "pyobjects_states" not in __context__:
        load_states()

    # these hold the scope that our sls file will be executed with
    _globals = {}

    # create our StateFactory objects
    mod_globals = {"StateFactory": StateFactory}
    for mod in __context__["pyobjects_states"]:
        mod_locals = {}
        mod_camel = "".join([part.capitalize() for part in mod.split("_")])
        valid_funcs = "','".join(__context__["pyobjects_states"][mod])
        mod_cmd = "{} = StateFactory('{!s}', valid_funcs=['{}'])".format(
            mod_camel, mod, valid_funcs)
        exec(mod_cmd, mod_globals, mod_locals)

        _globals[mod_camel] = mod_locals[mod_camel]

    # add our include and extend functions
    _globals["include"] = Registry.include
    _globals["extend"] = Registry.make_extend

    # add our map class
    Map.__salt__ = __salt__
    _globals["Map"] = Map

    # add some convenience methods to the global scope as well as the "dunder"
    # format of all of the salt objects
    try:
        _globals.update({
            # salt, pillar & grains all provide shortcuts or object interfaces
            "salt": SaltObject(__salt__),
            "pillar": __salt__["pillar.get"],
            "grains": __salt__["grains.get"],
            "mine": __salt__["mine.get"],
            "config": __salt__["config.get"],
            # the "dunder" formats are still available for direct use
            "__salt__": __salt__,
            "__pillar__": __pillar__,
            "__grains__": __grains__,
            "__opts__": __opts__,
            "__sls__": sls,
        })
    except NameError:
        pass

    # if salt_data is not True then we just return the global scope we've
    # built instead of returning salt data from the registry
    if not salt_data:
        return _globals

    # this will be used to fetch any import files
    client = get_file_client(__opts__)

    # process our sls imports
    #
    # we allow pyobjects users to use a special form of the import statement
    # so that they may bring in objects from other files. while we do this we
    # disable the registry since all we're looking for here is python objects,
    # not salt state data
    Registry.enabled = False

    def process_template(template):
        template_data = []
        # Do not pass our globals to the modules we are including and keep the root _globals untouched
        template_globals = dict(_globals)
        for line in template.readlines():
            line = line.rstrip("\r\n")
            matched = False
            for RE in (IMPORT_RE, FROM_RE):
                matches = RE.match(line)
                if not matches:
                    continue

                import_file = matches.group(1).strip()
                try:
                    imports = matches.group(2).split(",")
                except IndexError:
                    # if we don't have a third group in the matches object it means
                    # that we're importing everything
                    imports = None

                state_file = client.cache_file(import_file, saltenv)
                if not state_file:
                    raise ImportError(
                        "Could not find the file '{}'".format(import_file))

                with salt.utils.files.fopen(state_file) as state_fh:
                    state_contents, state_globals = process_template(state_fh)
                exec(state_contents, state_globals)

                # if no imports have been specified then we are being imported as: import salt://foo.sls
                # so we want to stick all of the locals from our state file into the template globals
                # under the name of the module -> i.e. foo.MapClass
                if imports is None:
                    import_name = os.path.splitext(
                        os.path.basename(state_file))[0]
                    template_globals[import_name] = PyobjectsModule(
                        import_name, state_globals)
                else:
                    for name in imports:
                        name = alias = name.strip()

                        matches = FROM_AS_RE.match(name)
                        if matches is not None:
                            name = matches.group(1).strip()
                            alias = matches.group(2).strip()

                        if name not in state_globals:
                            raise ImportError(
                                "'{}' was not found in '{}'".format(
                                    name, import_file))
                        template_globals[alias] = state_globals[name]

                matched = True
                break

            if not matched:
                template_data.append(line)

        return "\n".join(template_data), template_globals

    # process the template that triggered the render
    final_template, final_globals = process_template(template)
    _globals.update(final_globals)

    # re-enable the registry
    Registry.enabled = True

    # now exec our template using our created scopes
    exec(final_template, _globals)

    return Registry.salt_data()
Exemple #6
0
def render(template, saltenv='base', sls='',
           tmplpath=None, rendered_sls=None,
           _states=None, **kwargs):

    # these hold the scope that our sls file will be executed with
    _globals = {}
    _locals = {}

    # create our registry
    _registry = StateRegistry()

    # if we haven't been provided a list of states (which really only happens
    # from the tests) then try to use the __states__ global that the renderer
    # loader should provide (see commit cc8539f), if the global doesn't exist
    # (also usually from the tests) then we load the states ourself
    if _states is None:
        try:
            _states = __states__
        except NameError:
            from salt.loader import states
            __opts__['grains'] = __grains__
            __opts__['pillar'] = __pillar__
            _states = states(__opts__, __salt__)

    # build our list of states and functions that we will use to build our
    # StateFactory objects
    _st_funcs = {}
    for func in _states:
        (mod, func) = func.split(".")
        if mod not in _st_funcs:
            _st_funcs[mod] = []
        _st_funcs[mod].append(func)

    # create our StateFactory objects
    _st_globals = {'StateFactory': StateFactory, '_registry': _registry}
    for mod in _st_funcs:
        _st_locals = {}
        _st_funcs[mod].sort()
        mod_camel = ''.join([
            part.capitalize()
            for part in mod.split('_')
        ])
        mod_cmd = "%s = StateFactory('%s', registry=_registry, valid_funcs=['%s'])" % (
            mod_camel, mod,
            "','".join(_st_funcs[mod])
        )
        if sys.version > 3:
            exec(mod_cmd, _st_globals, _st_locals)
        else:
            exec mod_cmd in _st_globals, _st_locals
        _globals[mod_camel] = _st_locals[mod_camel]

    # add our include and extend functions
    _globals['include'] = _registry.include
    _globals['extend'] = _registry.make_extend

    # add some convenience methods to the global scope as well as the "dunder"
    # format of all of the salt objects
    try:
        _globals.update({
            # salt, pillar & grains all provide shortcuts or object interfaces
            'salt': SaltObject(__salt__),
            'pillar': __salt__['pillar.get'],
            'grains': __salt__['grains.get'],
            'mine': __salt__['mine.get'],

            # the "dunder" formats are still available for direct use
            '__salt__': __salt__,
            '__pillar__': __pillar__,
            '__grains__': __grains__
        })
    except NameError:
        pass

    # now exec our template using our created scopes
    # in py3+ exec is a function, prior to that it is a statement
    if sys.version > 3:
        exec(template.read(), _globals, _locals)
    else:
        exec template.read() in _globals, _locals

    return _registry.salt_data()