首页 文章

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

提问于
浏览
11

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

我有一个用户支柱 . 它是这样的:

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

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

users:
  new_user:
    sudouser: True

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

3 回答

  • 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
    ...
    

    另见:

  • 2

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

    答案很长:支柱不像状态树那样支持 extend 关键字,尽管在salt issue #3991上有一些对话 . 不幸的是,我并不知道有任何计划将其纳入氦气 .

    实际上,你最好确保你的支柱数据在每个人的基础上是不同的,然后你就不必担心碰撞了 . 您可以选择使用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支柱数据(更不用说难以维护)了 .

    对于它需要复制数据,并且更容易维护 . 当然,你最后用额外的未使用的密钥(例如 base_users )污染支柱,但在这种特殊情况下,我认为这是可以接受的 .

    希望这可以帮助!

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

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

    include:
        - common.base_users
    

    你可以做

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

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

  • 0

    我解决这个问题的方法是将列表值更改为dict

    /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状态(已安装,删除等)

相关问题