Python Jinja2的簡單使用

參考連接: https://jinja.palletsprojects.com/en/2.11.x/
下面測試使用jinja2版本: version = "2.11.2" , python版本: version = "3.7.4"node

Template使用

from jinja2 import Template
template = Template('Hello {{ name }}')
print(template.render(name='dsg'))
# > output: Hello dsg

template = Template('service: {{ service.name }}, version: {{ service.version }}')
service = {'name': 'mysql', 'version': 5.7}
print(template.render(service=service))
# > output: service: mysql, version: 3.7

template = Template('service: {{ service.name }}, version: {{ service.version }}')
service = {'service': {'name': 'mysql', 'version': 5.7}}
print(template.render(service))

template = Template('service list: {% for s in services %} {{s}};{% endfor %}')
services = {'services': ['mysql', 'nginx']}
print(template.render(services))
# > output: service list:  mysql; nginx;

去除空格python

template = Template('service list: {% for s in services -%} {{s}};{%- endfor %}')
services = {'services': ['mysql', 'nginx']}
print(template.render(services))
# > output: service list: mysql;nginx;

直接讀j2文件, j2文件示例:

# filename service.j2
name: {{ name }}
version: {{ version }}
with open('app/tmp/service.j2', 'r') as f:
    buffer = f.read()
    service = {'name': 'mysql', 'version': 5.7}
    template = Template(buffer)
    print(template.render(service))
# output:
# > name: mysql
# > version: 5.7

使用模板文件實現部署替換配置文件

# .
# |-- app
# |   |-- __init__.py   # 必須,
# |   |-- tmp
# |       |-- service.js   # 配置文件模板
# |       |-- nginx.js           # 配置文件模板
from jinja2 import Environment, PackageLoader

env = Environment(loader=PackageLoader('app', 'tmp'))
template = env.get_template('service.j2')
content = template.render(name='mysql', version='5.8')

with open('./config', 'w') as f:
    f.write(content)
print(content)
# output:
# > name: mysql
# > version: 5.7

import yaml
with open('app/config.yml') as f:
    y = yaml.safe_load(f)
    print(y)
    template = Template('basedir = {% for node in nodes %} {% if "nginx" in nodes[node].modules %} {{ nodes[node].basedir }} {% endif %}{% endfor %}')
    print(template.render(y))
# output:
# {'nodes': {'node1': {'host': '10.0.0.2', 'basedir': '/data1', 'modules': ['mysql', 'nginx']}, 'node2': {'host': '10.0.0.3', 'basedir': '/data2', 'modules': ['nginx']}}, 'services': {'mysql': {'config': {'port': 3306, 'passwd': 123456}}, 'nginx': {'config': {'port': 8088}}}}
# basedir =   /data1   /data2


env = Environment(loader=PackageLoader('app', 'tmp'))
template = env.get_template('nginx.j2')
content = template.render(y)

with open('./config', 'w') as f:
    f.write(content)
print(content)

nginx.j2文件內容:mysql

version: '2'
services:
  nginx:
    image: nginx:11
    container_name: nginx
    ports:
      - {{ services.nginx.config.port }}:80
    volumes:
    - {% for node in nodes -%} {%- if "nginx" in nodes[node].modules %}{{nodes[node].basedir}}{%- endif %} {%- endfor %}/nginx/logs/:/var/lib/nginx/logs/
    - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime
    restart: always
    networks:
      - default_bridge
networks:
  default_bridge:
    external: true

config.yml文件內容:nginx

nodes:
  node1:
    host: 10.0.0.2
    basedir: /data1
    modules:
      - mysql
      - nginx
  node2:
    host: 10.0.0.3
    basedir: /data2
    modules:
      - nginx

services:
  mysql:
    config:
      port: 3306
      passwd: 123456
  nginx:
    config:
      port: 8088

config文件最後寫入的內容:sql

version: '2'
services:
  nginx:
    image: nginx:11
    container_name: nginx
    ports:
      - 8088:80
    volumes:
    - /data1/data2/nginx/logs/:/var/lib/nginx/logs/
    - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime
    restart: always
    networks:
      - default_bridge
networks:
  default_bridge:
    external: true

上面並無獲得咱們想要的結果,若是nginx只在一臺機器部署的話,結果會是咱們想要的,可是多機部署就不行了。
這裏我建議儘可能少在模板文件中寫邏輯判斷,邏輯判斷應該用python去實現,咱們再真實環境中去替換nginx配置的basedir時都是by機器的,咱們能夠用python先解析出以下格式的數據:app

{'10.0.0.2':{'nginx':{'basedir':'/data1'}},
 '10.0.0.2':{'mysql':{'basedir':'/data1'}},
 '10.0.0.3':{'nginx':{'basedir':'/data2'}}
}

若是咱們要部署給10.0.0.2部署nginx時就可以正確獲取basedir了。 具體怎麼實現, 看你們了。測試

yml裏面字典和列表

config.ymlrest

nodes:
  node1:
    host: 10.0.0.2
    basedir: /data1
    modules:
      - mysql
      - nginx
  node2:
    host: 10.0.0.3
    basedir: /data2
    modules:
      - nginx
template = Template(' {{ nodes }}')
print(template.render(y))
# 輸出:
 {'node1': {'host': '10.0.0.2', 'basedir': '/data1', 'modules': ['mysql', 'nginx']}, 'node2': {'host': '10.0.0.3', 'basedir': '/data2', 'modules': ['nginx']}}

config.xmlcode

nodes:
  - node1:
      host: 10.0.0.2
      basedir: /data1
      modules:
        - mysql
        - nginx
  - node2:
      host: 10.0.0.3
      basedir: /data2
      modules:
        - nginx
template = Template(' {{ nodes }}')
print(template.render(y))
# 輸出:
[{'node1': {'host': '10.0.0.2', 'basedir': '/data1', 'modules': ['mysql', 'nginx']}}, {'node2': {'host': '10.0.0.3', 'basedir': '/data2', 'modules': ['nginx']}}]

yml格式不一樣,取值就會不一樣。xml

相關文章
相關標籤/搜索