【问题标题】:Saltstack - Parsing YAML properties file to set Jinja variables - For loopSaltstack - 解析 YAML 属性文件以设置 Jinja 变量 - For 循环
【发布时间】:2017-07-28 13:36:30
【问题描述】:

我尝试使用 Jinja 解析属性文件以设置变量。

我在这个文件中有多个类别和子类别,例如:

  • jboss_container
    • 一些属性
    • foobar
  • jboss_datasource_install
    • 数据源1
      • 道具1
      • 道具2
    • 数据源2
  • jboss_app_deploy
    • app1
    • app2

目标是设置每个类别的变量并在 for 循环中重用它们。 --> 例如,我想在每个子类别上安装 2 个 jboss 数据源和循环

foobar.properties.yml:

jboss_container:
    jboss_container_values:
      jboss_container_install: 'True'
      jboss_app_name: 'foobar'
      jboss_version: 'x.x.x'
      ...

jboss_datasource_install:
    datasource1:
      jboss_datasource_install: 'True'
      jboss_datasource_name: 'foobar'
      jboss_datasource_jta: 'true'
      ...
    datasource2:
      jboss_datasource_install: 'True'
      ...

init.sls:

{% import_yaml 'foobar_properties.yml' as jboss_apps %}

% for jboss_container, jboss_container_values in jboss_apps.iteritems() %}
      {% for key, value in jboss_container_values.items() %}
                  {% if value.get('jboss_container_install') != 'False' %}

# Do stuff - {{ value.jboss_app_name }}

                  {% endif %}
      {% endfor %}
{% endfor %}

{% for jboss_datasource_install, jboss_datasource_install_name in jboss_apps.iteritems() %}
      {% for key, value in jboss_datasource_install_name.items() %}
                  {% if value.get('jboss_datasource_install') != 'False' %}

# Do stuff - {{ value.jboss_datasource_install }}

                  {% endif %}
      {% endfor %}
{% endfor %}

在Salt中居然出现了这个错误:

Jinja 变量 'dict object' 没有属性 'jboss_app_name'

任何想法如何做到这一点?

非常感谢:)

【问题讨论】:

    标签: variables properties yaml jinja2 salt-stack


    【解决方案1】:

    您的外循环遍历jboss_datasource_install,您的内循环遍历datasource1。你的if 然后要求

    value.get('jboss_container_install')
    

    dict 不包含名为jboss_container_install 的键,因此它返回None。由于这不等于'False',Jinja 然后尝试插入value.jboss_app_name,这是错误的来源。

    一个简单的解决方法是将if-Statement 重写为:

    {% if value.get('jboss_container_install') == 'True' %}
    

    但是无论如何,您的外部循环似乎很奇怪。如果只想遍历jboss_container,可以替换

    {% for jboss_container, jboss_container_values in jboss_apps.iteritems() %}
      {% for key, value in jboss_container_values.items() %}
    

    {% for key, value in jboss_apps['jboss_container']['jboss_container_values'].iteritems() %}
    

    【讨论】:

    • value == True 的修复对我来说非常有效。谢谢
    • 但是 {% for key, value in jboss_apps['jboss_container']['jboss_container_values'] %} 失败并出现错误:失败:Jinja 错误:要解压的值太多
    • 缺少一个iteritems(),我已修复。
    【解决方案2】:

    幸运的是:

    {% for key, value in jboss_apps['jboss_container']['jboss_container_values'].iteritems() %} 
    {% if value.get('jboss_container_install') == 'True' %}
    # Do stuff - {{ value.jboss_app_name }}
    

    我收到了这个错误: 失败:Jinja 变量 'str object' 没有属性 'get'

    没有 If 语句,我得到了这个错误: 失败:Jinja 变量 'str object' 没有属性 'jboss_app_name'

    如果我尝试使用 {{ jboss_app_name }} 而不是 {{ value.jboss_app_name }},则会发生同样的错误。

    【讨论】:

    • 我已经修改了我的 if 语句:{% if value["jboss_container_install"] == 'True' %} 现在我有一个新错误:失败:Jinja 变量 'str object' 没有属性 'jboss_container_install'
    • 我的 Yaml 属性文件中的占位符 (*/&) 有问题。如果我删除占位符,它可以工作......但我需要多次更改同一个变量......
    猜你喜欢
    • 2021-02-19
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 2018-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多