• 理解 JINJA 模板


    UNDERSTANDING JINJA

    jinja是sls文件是默认的模板语言


    JINJA IN STATES

    在state文件被运行之前需要将文件中jinja模板语言部分处理掉,处理完之后再转化成YAML格式,最后变成python数据结构。
    jinja模板语法通常被用于在state文件中使用控制结构,如if条件,for循环等,可以达到消除冗余数据的效果。

    在sls文件中使用jinja模板
    示例:

     1 {% if grains['os'] != 'FreeBSD' %}
     2 tcsh:
     3     pkg:
     4         - installed
     5 {% endif %}
     6 
     7 motd:
     8   file.managed:
     9     {% if grains['os'] == 'FreeBSD' %}
    10     - name: /etc/motd
    11     {% elif grains['os'] == 'Debian' %}
    12     - name: /etc/motd.tail
    13     {% endif %}
    14     - source: salt://motd
    View Code

    解析:

      依据minion端的os系统来部署不同的配置文件,但是上面的例子在jinja模板使用的代码可能过于冗余,代码内容的用途过于单一,它的作用仅能体现在一个文件的传输模块中。

      所以为了优化这种情况,name应该使用pillar变量,将这种判断逻辑包含到pillar环境里面,又或者将这种逻辑放在一个基础jinja模板中被继承,实现解耦,便于后续的变更。

    jinja循环控制结构的示例:

     1 {% set motd = ['/etc/motd'] %}
     2 {% if grains['os'] == 'Debian' %}
     3   {% set motd = ['/etc/motd.tail', '/var/run/motd'] %}
     4 {% endif %}
     5 
     6 {% for motdfile in motd %}
     7 {{ motdfile }}:
     8   file.managed:
     9     - source: salt://motd
    10 {% endfor %}
    View Code

    在filter_by里面应用grains变量,相当于把逻辑放在另一个模板中了,可以被其他sls文件中的模板包引用

    1 {% set auditd = salt['grains.filter_by']({
    2 'RedHat': { 'package': 'audit' },
    3 'Debian': { 'package': 'auditd' },
    4 }) %}
    View Code

    依据minion端变量auditd的值来指定包名


    INCLUDE AND IMPORT

    包含和导入可用于sls文件只共享通用的可配置的内容
    示例:

    1 {% from 'lib.sls' import test %}
    2 {% from 'lib.sls' import test with context %}
    View Code

    INCLUDING CONTEXT DURING INCLUDE/IMPORT

    {% import 'openssl/vars.sls' as ssl with context %}
    #使用with context将变量的上下文也包含进来


    MACROS

    宏定义,宏的使用有利于消除代码的冗余

    示例:

     1 # init.sls
     2 {% from 'lib.sls' import pythonpkg with context %}
     3 
     4 python-virtualenv:
     5   pkg.installed:
     6     - name: {{ pythonpkg('virtualenv') }}
     7 
     8 python-fabric:
     9   pkg.installed:
    10     - name: {{ pythonpkg('fabric') }}
    View Code

    使用了一个include包含另一个sls文件

    1 # lib.sls
    2 {% macro pythonpkg(pkg) -%}
    3   {%- if grains['os'] == 'FreeBSD' -%}
    4     py27-{{ pkg }}
    5   {%- elif grains['os'] == 'Debian' -%}
    6     python-{{ pkg }}
    7   {%- endif -%}
    8 {%- endmacro %}
    View Code

    定义了一个宏pythonpkg,用于做变量替换,利用一个预设的规则对引用的变量做逻辑处理


    TEMPLATE INHERITANCE

    模板继承,参考jinja的模板语言中的继承逻辑和使用逻辑


    FILTERS

    过滤器

    strftime
      将与时间有关的对象转化成基于时间的字符串,需要系统timelib库的支持
    示例:

    1 {% set curtime = None | strftime() %}
    2 {{ "2002/12/25"|strftime("%y") }}
    3 {{ "1040814000"|strftime("%Y-%m-%d") }}
    4 {{ datetime|strftime("%u") }}
    5 {{ "tomorrow"|strftime }}
    View Code

    yaml_encode
    用于对一些需要特殊的字符做yaml转换

    JINJA IN FILES
      jinja在文件中的使用
    示例:

     1 # redis.sls
     2 /etc/redis/redis.conf:
     3     file.managed:
     4         - source: salt://redis.conf
     5         - template: jinja
     6         - context:
     7             bind: 127.0.0.1
     8 
     9 # lib.sls
    10 {% set port = 6379 %}
    11 
    12 # redis.conf
    13 {% from 'lib.sls' import port with context %}
    14 port {{ port }}
    15 bind {{ bind }}
    View Code

    文件中的内容可以关联到外部模板文件中预设好的逻辑中,实现灵活配置。


    ESCAPING JINJA

    jinja语法转义

    比较简单的转义:
      {{ '{{' }}

    成块的转义:

    1 {% raw %}
    2     some text that contains jinja characters that need to be escaped
    3 {% endraw %}
    View Code

    CALLING SALT FUNCTIONS

    jinja中可以使用salt函数,可以的函数列表可以参考以下链接:

    两个等价函数的使用示例:
      {{ salt['cmd.run']('whoami') }}
      {{ salt.cmd.run('whoami') }}


    DEBUGGING

    show_full_context可用于输出当前上下文的变量值,便于debug分析排查问题
    示例:
      Context is: {{ show_full_context() }}


    CUSTOM EXECUTION MODULES

    如何使用自定义的模块

      {{ salt['my_custom_module.my_custom_function']() }}

    关于编写自有执行模块参考以下两个:

    (1)一个执行模块在jinja语法中如何被执行
      https://docs.saltstack.com/en/2016.11/topics/tutorials/jinja_to_execution_module.html#tutorial-jinja-to-execution-module
    (2)如何写一个执行模块
      https://docs.saltstack.com/en/2016.11/ref/modules/index.html#writing-execution-modules

      关于执行模块后续再深究。

    思考:宏的定义和之前的变量定义逻辑有何不同?

         宏定义能实现一组变量特定逻辑的处理,如果将多个变量定义放在普通的模板变量定义逻辑里面,一千个变量就需要定义一千次,而宏只需要定义一个规则,调用的时候自动

         应用即可。

  • 相关阅读:
    Atitit flowable使用总结 目录 1. flowable 1 1.1. 添加依赖 1 1.2. Flowable的启动接口 2 2. 还是使用简单流程来完成业务流程的学习, 2 2.1.
    dell xps15 9550安装黑苹果
    显示器色域
    数据标准化的方法与意义
    XPS9550困扰我的散热问题终于解决了
    app开发
    纹理
    用 Java 开发一个打飞机小游戏(附完整源码)
    Spring Cloud Gateway 限流实战,终于有人写清楚了!
    OracleJDK 和 OpenJDK 有什么区别?来看看大神的回答!
  • 原文地址:https://www.cnblogs.com/solitarywares/p/7470497.html
Copyright © 2020-2023  润新知