从状态模块中调用状态模块

Call state module from within state module

我正在写一个 custom state module 目的是在给定位置创建一个具有(部分)可配置内容的文件。

基本上我希望缩短以下 SLS(为了这个问题的目的而简化,实际上更复杂)...

/etc/foo/bar:
  file.managed:
    - contents: Hello World

...为此:

bar:
  my_module.foo:
    - message: World

由于此功能基本上是 file.managed 状态的更专用版本,因此在我的自定义状态模块中重新使用 file.managed 状态对我来说很有用。

有没有办法从我自己的状态模块调用file.managed状态模块?


我已经尝试过的(未成功):

  1. 正在导入 salt.states.file 并调用 salt.states.file.managed:

    import salt.states.file
    
    def foo(name, message, **kwargs):
        return salt.states.file.managed(name='/etc/foo/%s' % name,
                                        contents='Hello %s' % message, 
                                        **kwargs)
    

    这会导致错误消息:

      File "/usr/lib/python2.7/dist-packages/salt/state.py", line 1626, in call
        **cdata['kwargs'])
      File "/usr/lib/python2.7/dist-packages/salt/loader.py", line 1492, in wrapper
        return f(*args, **kwargs)
      File "/var/cache/salt/minion/extmods/states/my_module.py", line 14, in static_pod
        contents=yaml.dump(data, default_flow_style=False), **kwargs)
      File "/usr/lib/python2.7/dist-packages/salt/states/file.py", line 1499, in managed
        mode = __salt__['config.manage_mode'](mode)
    NameError: global name '__salt__' is not defined
    
  2. 使用__salt__['file.managed']:

    def foo(name, message, **kwargs):
        return __salt__['file.managed'](name='/etc/foo/%s' % name,
                                        contents='Hello %s' % message, 
                                        **kwargs)
    

    这也会导致(不同的)错误消息(这并不奇怪,因为文档明确指出 __salt__ 仅包含 execution 模块,而不包含 状态模块):

      File "/usr/lib/python2.7/dist-packages/salt/state.py", line 1626, in call
        **cdata['kwargs'])
      File "/usr/lib/python2.7/dist-packages/salt/loader.py", line 1492, in wrapper
        return f(*args, **kwargs)
      File "/var/cache/salt/minion/extmods/states/my_module.py", line 13, in static_pod
        return __salt__['file.managed'](name='/etc/foo/%s' % name,
      File "/usr/lib/python2.7/dist-packages/salt/loader.py", line 900, in __getitem__
        func = super(LazyLoader, self).__getitem__(item)
      File "/usr/lib/python2.7/dist-packages/salt/utils/lazy.py", line 93, in __getitem__
        raise KeyError(key)
    KeyError: 'file.managed'
    

我找到了使用 state.single 执行模块的解决方案:

def foo(name, messsage):
    result = __salt__['state.single'](fun='file.managed',
                                      name='/etc/foo/%s' % name,
                                      contents='Hello %s' % message,
                                      test=__opts__['test'])
    return result.items()[0][1]

state.single 模块 return 的数据结构如下所示:

{
  'file_|-/etc/foo/bar_|-/etc/foo/bar_|-managed': {
    'comment': 'The file /etc/foo/bar is set to be changed',
    'name': '/etc/foo/bar',
    'start_time': '08:24:45.022518',
    'result': None,
    'duration': 18.019,
    '__run_num__': 0,
    'changes': {'diff': '...'}
  }
}

内部对象(file_|-/etc/foo/bar_|-/etc/foo/bar_|-managed 下的所有内容)是 file.managed 模块本身 return 的内容,因此您可以将此值重新用作自定义状态的 return值。