无法在salt runner中获取支柱

1 投票
1 回答
36 浏览
提问于 2025-04-14 16:47

我正在用SaltStack写一个自定义的运行器,目的是在saltmaster上进行一些操作。不过,我无法在这个运行器中调用到柱子(pillars)。

这些秘密信息存储在柱子里,和saltmaster的id有关,比如在pillar的top.sls文件中。

prd:
    'my_saltmaster':
        - match: pcre
        - salt_secrets

这是我尝试过的内容

import salt.runner
import logging

log = logging.getLogger(__name__)

runner = salt.runner.Runner(__opts__)
secret = runner.cmd(fun='salt.cmd', arg=['pillars.get', 'my_secret'])
log.info(f"my_secret = {secret}")

输出结果

my_secret =

我查看了官方的源代码,但没有找到有用的信息。如果你能帮我解答一下,那就太好了。

1 个回答

1

如果你想调用模块函数 salt.cmd,你还需要传递一个叫 with_pillar 的参数,这样才能启用柱状数据的渲染,具体可以参考官方的文档

另外,你可能还需要把参数改成 pillar,而不是 pillars

secret = runner.cmd(fun='salt.cmd', arg=['pillar.get', 'my_secret'],  kwargs={"with_pillar": True})

不过,我不太推荐这种做法,主要有两个原因:

  1. 这个方法假设你的 saltmaster 的 id 和你在 top.sls 中指定的 minion id 是一致的,但实际上这种情况很少见,因为 master 的 id 通常会加上 _master 后缀,后面跟着它运行的主机名(默认情况下)。

  2. 这个方法非常繁琐,而且成本高。为什么呢?因为它不仅首先调用了 runner 客户端,然后再调用 runner 的 salt 模块,最后还要调用 pillar 模块!

更好的方法是直接导入并使用 pillar 模块,如下所示,这样可以省去很多不必要的操作:

import salt.pillar
import salt.runner
import logging

log = logging.getLogger(__name__)

runner = salt.runner.Runner(__opts__)

master_id = "my_saltmaster"
grains = None # specify any grain if required to render your top.sls

# Load required pillars
# deepcopy because we don't want to modify the actual __opts__
opts = copy.deepcopy(__opts__)
opts['pillar'] = salt.pillar.get_pillar(
    opts,
    grains,
    master_id,
    saltenv=opts['saltenv'],
    pillarenv=opts.get('pillarenv')).compile_pillar()

# extract required secret key from the pillar
my_secret = opts['pillar'].get('my_secret', None)
log.info(f"my_secret = {my_secret}")

想了解更多关于 pillar 模块的代码,可以在这里查看哦 :)

撰写回答