在Salt状态之间共享变量

112次阅读
没有评论

问题描述

在使用Salt进行部署和配置管理时遇到了一个问题。他需要在连接到FreeIPA服务器之前,随机生成一个OTP令牌,并将其用于连接到IPA。他想知道如何在不同的SLS文件之间共享变量。

以以下示例为例:

init.sls:

{%- from "freeipa/map.jinja" import client, ipa_host with context %}
include:
  - freeipa.example
freeipa_client_install:
  cmd.run:
    - name: >
      ipa-client-install
      --server server.example.com
      --domain example.com
      --realm EXAMPLE.COM
      --hostname client.example.com
      -w {{ otp }}                                   <===== !!!
      --unattended

./freeipa/example.sls:

{% set otp = salt['random.get_str'](20) %}         <===== !!!
get_ticket:
  cmd.run:
    - name: kinit service-account@EXAMPLE.COM -kt /tmp/salt-service.keytab
ipa_host_add:
  cmd.run:
    - name: >
      curl -k
      -H referer:https://{{ client.get("server", {}) }}/ipa
      --negotiate -u :
      -H "Content-Type:application/json"
      -H "Accept:applicaton/json"
      -c /tmp/cookiejar -b /tmp/cookiejar
      -X POST
      -d '{
        "id": 0,
        "method": "host_add",
        "params": [
          [
            "client.example.com"
          ],
          {
            "all": false,
            "force": false,
            "no_members": false,
            "no_reverse": false,
            "random": false,
            "raw": true,
            "userpassword": "{{ otp }}",          <==== !!!
            "version": "2.156"
          }
        ]
      }' https://server.example.com/ipa/json

用户在init.sls中无法引用在example.sls中设置的变量。他想知道是否需要在init.sls中使用salt['random.get_str'](20)来生成变量。如果是这样的话,他应该如何在example.sls中引用在init.sls中设置的变量,或者反过来,如何在init.sls中引用在example.sls中设置的变量?

解决方案

以下是针对你的问题的解决方案,注意根据具体情况做适当修改。

解决方案1:将变量定义移到init.sls

在Salt中,SLS文件中的变量是由Jinja渲染引擎处理的,而Jinja的渲染是按照从上到下的顺序进行的。因此,在不同的SLS文件之间共享变量,你需要确保变量的定义在使用之前已经被渲染。

在你的情况下,你可以将otp变量的定义移到init.sls中,以确保它在使用之前已经被渲染。下面是相应的更改:

init.sls:

{%- from "freeipa/map.jinja" import client, ipa_host with context %}
include:
  - freeipa.example
{%- set otp = salt['random.get_str'](20) %}         <===== !!!
freeipa_client_install:
  cmd.run:
    - name: >
      ipa-client-install
      --server server.example.com
      --domain example.com
      --realm EXAMPLE.COM
      --hostname client.example.com
      -w {{ otp }}
      --unattended

./freeipa/example.sls:

get_ticket:
  cmd.run:
    - name: kinit service-account@EXAMPLE.COM -kt /tmp/salt-service.keytab
ipa_host_add:
  cmd.run:
    - name: >
      curl -k
      -H referer:https://{{ client.get("server", {}) }}/ipa
      --negotiate -u :
      -H "Content-Type:application/json"
      -H "Accept:applicaton/json"
      -c /tmp/cookiejar -b /tmp/cookiejar
      -X POST
      -d '{
        "id": 0,
        "method": "host_add",
        "params": [
          [
            "client.example.com"
          ],
          {
            "all": false,
            "force": false,
            "no_members": false,
            "no_reverse": false,
            "random": false,
            "raw": true,
            "userpassword": "{{ otp }}",
            "version": "2.156"
          }
        ]
      }' https://server.example.com/ipa/json

通过将变量定义移到init.sls中,你可以确保otp变量在整个SLS文件中都是可用的。

解决方案2:使用Salt的grains或pillar

另一种方法是使用Salt的grains或pillar来共享变量。这些机制允许你在不同的SLS文件之间存储和访问数据。

  1. 使用grains:
    在需要设置otp变量的SLS文件中,可以使用grains.set来设置grain值,然后在其他需要访问该值的SLS文件中使用grains.get来获取值。这样,你可以在不同的SLS文件之间共享变量。

示例:

# 在example.sls中设置grain
{%- set otp = salt['random.get_str'](20) %}
{% set grains_data = {'otp': otp} %}
{% salt['grains.set'](grains=grains_data) %}

# 在init.sls中获取grain
{%- from "freeipa/map.jinja" import client, ipa_host with context %}
include:
  - freeipa.example
{%- set otp = salt['grains.get']('otp') %}
freeipa_client_install:
  cmd.run:
    - name: >
      ipa-client-install
      --server server.example.com
      --domain example.com
      --realm EXAMPLE.COM
      --hostname client.example.com
      -w {{ otp }}
      --unattended
  1. 使用pillar:
    类似地,你可以使用pillar来存储和访问共享变量。在pillar中设置变量,然后在不同的SLS文件中使用pillar.get来获取值。

无论你选择使用grains还是pillar,都可以实现在不同的SLS文件之间

正文完