如何加入两个Salt支柱文件并合并数据?

时间:2014-07-08 11:56:12

标签: salt-stack

有没有办法加入两个支柱文件?

我有一个用户支柱。它类似于:

users:
  joe:
    sudouser: True
  jack:
    sudouser: False

现在我需要为某些服务器设置不同的用户(即将一些用户添加到一台服务器)。所以我创建了新的支柱文件:

users:
  new_user:
    sudouser: True

并将此topfile分配给服务器。但因为键是相同的,它会覆盖第一个键。如果我改变它,我需要更新状态文件(我真的不想要)。我该如何处理这个问题?有没有办法告诉盐"合并"文件?

3 个答案:

答案 0 :(得分:11)

至少可以根据the latest Salt documentation about pillar(截至5188d6c)说明:

  

小心点,只要避免冲突,支柱命名空间就可以合并单个密钥下的多个支柱文件中的内容......

我在Salt Helium(2014.7.0)下进行了测试,它按预期工作。


您的示例

支柱文件user_set_a.sls

users:
  joe:
    sudouser: True
  jack:
    sudouser: False

支柱文件user_set_b.sls

users:
  new_user:
    sudouser: True

运行pillar.items以确认所有用户都在同一users密钥下合并:

salt-call pillar.items
...
    users:
    ----------
    jack:
        ----------
        sudouser:
            False
    joe:
        ----------
        sudouser:
            True
    new_user:
        ----------
        sudouser:
            True
...

另见:

答案 1 :(得分:2)

简短回答:你不能以这种方式合并支柱数据。

答案很长:虽然在salt issue #3991上有一些对话,但支柱不支持extend关键字与状态树相同。不幸的是,目前似乎没有任何真正的动力,我不知道有任何计划将其纳入氦气。

实际上,你最好确保你的支柱数据在每个人的基础上是不同的,然后你就不必担心碰撞了。您可以选择使用YAML锚点和引用执行某些操作,例如

# common/base users.sls
base_users: &base_users
    user1:
       foo: bar
    user2:
       baz: bat

# minion1.sls
{% include 'common/base_users.sls' %}

users:
    <<: *base_users
    user3:
        qux: quux

# minion2.sls
{% include 'common/base_users.sls' %}

users:
    <<: *base_users
    user4:
        corge: grault

另一个潜在的(hacky)选项是使用外部支柱模块并对提供给模块的支柱键进行某种全局匹配,因此您基本上可以使用merge-thing-abc123merge-thing-def456等键,使用merge前缀按thing进行分组并合并数据。我不会真的推荐这个,因为它是一个非常明显的反模式WRT支柱数据(更不用说难以维护)。

对于它的价值,这也是偶尔让我感到沮丧的事情,但我最终决定一些最小的数据重复比提出一个解决方法更好。使用YAML引用,这可能是一个更合适的选项,因为从技术上讲,您不需要复制数据,并且更容易维护。当然,你最后会用额外的未使用的密钥(例如base_users)污染支柱,但在这种特殊情况下,我认为这是可以接受的。

希望这有帮助!

编辑:我说得太早了;它看起来好像包含在被注入包含文件之前被解析,因此在这种情况下锚点/引用将不起作用。调查一下,会更新。

编辑2 :刚刚发现,由于状态和支柱文件本质上都是Python模块,因此它们可以包含在Jinja中,而不是使用支柱的包含。所以,而不是

include:
    - common.base_users

你可以做到

{% include 'common/base_users.sls' %}

然后继续引用所包含文档中定义的任何锚点。更新了原始答案以说明这一点(已验证可以正常工作)。

答案 2 :(得分:0)

例如,通过解决方法是将列表值更改为字典。

/srv/pillar/common/packages.sls

packages:
   htop: { pkg=installed }
   rsync: { pkg=removed }
   wget: { pkg=installed }



/srv/pillar/servers/nycweb01.sls
packages:
  nginx: { pkg=installed }

检查此服务器支柱项目,您可以看到它结合了来自公共支柱和每个节点支柱的数据,

salt-ssh nycweb01 pillar.items

nycweb01:
    ----------
    packages:
        ----------
        htop:
            ----------
            pkg=installed:
                None
        nginx:
            ----------
            pkg=installed:
                None
        rsync:
            ----------
            pkg=removed:
                None
        wget:
            ----------
            pkg=installed:

在状态文件中,您可以使用pkg名称和pkg状态(已安装,已删除等)